如何获取uiview的任何信息(可视调试器报告的原始地址)

时间:2019-04-08 11:52:10

标签: swift xcode lldb

我有一棵要查看的UIViews树: UIPageViewController的高度是状态栏的高度过高,而底部的foobar在某处 层次结构下降到窗口房地产高度以下。 这是我对lldb的不解之谜:

(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'

2 个答案:

答案 0 :(得分:1)

  1. 您的星号太多。

  2. 您不能使用属性符号。

  3. 您需要使用po

例如,这应该起作用:

po [((UIView*)0x83fcc6d0) accessibilityIdentifier]

但是,我更喜欢使用的技术是谈论Swift:

expr -l Swift -- import UIKit
expr -l Swift -- let $v = unsafeBitCast(0x83fcc6d0, to: UIView.self)
expr -l Swift -- print($v.accessibilityIdentifier)

答案 1 :(得分:0)

停在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]

作为表达式或子表达式,我们将其重写为:

[(id) <some expression whose type we don't know> someSelector]

这似乎是一种合理的帮助,因为向其发送ObjC消息唯一有意义的是“ id”。因此,任何错误都是无意义的错误,因此希望可能性较小。这确实意味着一连串方法访问,当等效时,所有返回“ id”的事件都将得到解析。表单将使类型检查器失败。

这是在调试时处理不完整类型信息的所有麻烦。请注意,通过使用模块(-fmodule-gmodule)构建程序或等效地通过发出以下命令,可以解决许多问题:

(lldb)表达式@import UIKit

作为调试会话的一部分。然后lldb将了解UIKit中的所有类型,并且表达式解析器可以做得更好。