2013年7月8日 星期一

iOS UIView 除錯

Refernece: Visual View Debugging | Cocoanetics

這篇實在是太實用了, 備忘一下文中提到的技巧。

取得 view 資訊

NSLog(@"%@", view);

直接輸出 UIView 即可, 不用自己笨笨的輸出 frame 之類的資訊。

輸出 view 的巢狀結構

NSLog(@"%@", [view recursiveDescription]);

[UIView recursiveDescription] 是 private method, 不過 Objective-C 有 dynamic typing 的特性, 真的要呼叫的話, 系統也不會擋你, 只是編譯時有個 warning 而已。這功能相當實用, 可以確保相關的 view 是否有加進去, 了解 sub views 之間的順序 (後面的 view 會蓋掉前面的 view)。

在多個關鍵處輸出 recursive description 後, 才發覺我在某處不小心刪掉某個 view 沒加回去。若沒有這項功能, 執行後只知道沒出現這個 view, 到底是放錯位置、沒放進去或被覆蓋掉, 完全是一無所知啊。

畫出 view 的外框

view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 1.0;

使用上述程式的前置動作為:

  • linking 加入 QuartzCore.framework
  • 程式加上 #import <QuartzCore/QuartzCore.h>

2014-07-23 更新

  • [UIView recursiveDescription] 會顯示本身整層的結構, 若想看更上層的結構, 要往上存取 superview。但在 lldb 中打 po view.superview.superview 會失敗, 原因是 view.superview 傳回 id, 而 id 沒有型別, 無法直接呼叫 superview。所以要寫成 po ((UIView*)view.superview).superview。一但取得目標 UIView 的位置後 (例如 0x12345678), 再來就可以用 po [(UIView*)0x12345678 recursiveDescription] 得到目標的結構。
  • 承上, 更方便的作法是在 app 產生 UIWindow 的時候設中斷點, 取得 UIWindow 的位置 (例如 0x87654321), 之後隨時想看目前整個畫面的結構, 就按 XCode 的「暫停鍵」中斷程式進入 lldb, 再用 [(UIView*)0x87654321 recursiveDescription] 取得目前畫面的 UIView 結構。很快地了解 UIView 結構後, 要了解程式行為就容易多了。而且從 recursiveDescription 得知所有 subview 的位置後, 也可以配合轉型直接輸出各個 view 的其它屬性, 像是 [(UIScrollView*)0x12341234 zoomScale]。

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...