Swift 如何获取uiview(可视调试器报告的原始地址)的任何信息
我有一个UIViews树,我正试图理解: UIPageViewController的高度是一个状态栏的高度太高,不知怎么的,底部是中某个地方的foobar 该层次结构按高度下降到窗口下方。 以下是我在lldb的不幸经历:Swift 如何获取uiview(可视调试器报告的原始地址)的任何信息,swift,xcode,lldb,Swift,Xcode,Lldb,我有一个UIViews树,我正试图理解: UIPageViewController的高度是一个状态栏的高度太高,不知怎么的,底部是中某个地方的foobar 该层次结构按高度下降到窗口下方。 以下是我在lldb的不幸经历: (lldb) p (*(UIView*)0x83fcc6d0).accessibilityIdentifier error: 'UIView' does not have a member named 'accessibilityIdentifier' (lldb) p ((U
(lldb) p (*(UIView*)0x83fcc6d0).accessibilityIdentifier
error: 'UIView' does not have a member named 'accessibilityIdentifier'
(lldb) p ((UIView*)0x83fcc6d0).accessibilityIdentifier
error: property 'accessibilityIdentifier' not found on object of type 'UIView *'
(lldb) p ((UIView*)0x83fcc6d0)->accessibilityIdentifier
error: 'UIView' does not have a member named 'accessibilityIdentifier'
(lldb) p (*(UIView*)0x83fcc6d0).superview
error: 'UIView' does not have a member named 'superview'
(lldb) p (*(UIView*)0x83fcc6d0).superView
\error: 'UIView' does not have a member named 'superView'
(lldb) v (*(UIView*)0x83fcc6d0).superView
(lldb) po (*(UIView*)0x83fcc6d0).superView
error: 'UIView' does not have a member named 'superView'
po
po [((UIView*)0x83fcc6d0) accessibilityIdentifier]
然而,我更喜欢使用的技巧是快速交谈:
expr -l Swift -- import UIKit
expr -l Swift -- let $v = unsafeBitCast(0x83fcc6d0, to: UIView.self)
expr -l Swift -- print($v.accessibilityIdentifier)
在ViewController的viewDidLoad中停止,您可以像在代码中一样访问“view”属性:
(lldb) expr self.view
(UIView *) $0 = 0x0000000100615150
现在我们有了UIView的地址,让我们尝试访问它的属性:
(lldb) expr ((UIView *) 0x0000000100615150).frame
(CGRect) $5 = (origin = (x = 0, y = 0), size = (width = 768, height = 1024))
该物业为vrs。方法表示法“应该”只是编译器中的自动替换。但是,当我们不知道属性的类型时,在调试器的表达式解析器中使用属性访问可能会遇到麻烦,尤其是在链接属性时
原因是,如果lldb使用标量调用约定调用结构返回函数(如UIView的“frame”属性),那么它实际上是不安全的(可能会损坏被调试对象的堆栈)。所以lldb非常小心,在调用表达式之前,它知道表达式中元素的类型。如果lldb无法从调试信息中找到它,则可能需要额外的强制转换以使类型检查器满意
注意,lldb对我们知道表达式中的类型这一要求有一个例外,这可能会解释您提到的差异。如果我们看到:
[<some expression whose type we don't know> someSelector]
[someSelector]
这似乎是一个合理的帮助,因为向其发送ObjC消息唯一有意义的是一个“id”。因此,任何错误都将是荒谬的,因此希望不太可能。这确实意味着一个方法访问链,所有返回的“id”都将在等价项出现时得到解析。表单将无法通过类型检查器
这是在调试时处理不完整类型信息的所有麻烦之处。注意,通过使用模块(-fmodule
和-gmodule
)构建您的程序,或者通过发布以下命令来等效地解决这些问题:
(lldb)表达式@import-UIKit
作为调试会话的一部分。然后lldb将知道UIKit中的所有类型,表达式解析器可以做得更好。可能是重复的(虽然我已经回答了这个问题;也许我应该作为一个dup关闭)。是的,它似乎是一个dup。我没有我还没来得及检查这两个回复的有效性。你可以在一般情况下使用属性表示法。如果我们没有属性(位于实现文件中)的完整定义,您可能必须为属性(self.view.superview或类似内容)的属性提供类型转换。@JimIngham您是专家(因此我很高兴您在这里)。我所知道的是,我可以复制他的结果,但在使用属性表示法时无法以任何方式解决它,但可以通过切换到方法表示法来解决它。
[(id) <some expression whose type we don't know> someSelector]