Xcode - 如何与lldb地址交互并发送消息

时间:2014-12-04 11:54:24

标签: ios xcode debugging lldb

我在lldb中调试我的应用程序并需要向对象发送消息。 我没有对象变量名称(即self.object)而是该对象的地址。 例如,我有UIGestureRecognizer这个我无法访问的变量,并且地址如下:

0x7fe110297360

我想发送一条与手势识别器配合使用的消息:

[gestureA requireGestureToFail:gestureB];

所以我把它翻译成几个变种 - 每个都不成功:

expr [0x7fe110297360 requireGestureToFail:0x7fe10e842c00]
expr (long)[((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]
expr -- [0x7fe110297360 requireGestureToFail:0x7fe10e842c00]
expr -- (long)[((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]
expr [((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]

每个都被确认错误:

error: warning: receiver type 'long' is not 'id' or interface pointer, consider casting it to 'id'
error: no known method '-requireGestureToFail:'; cast the message send to the method's return type
error: 1 errors parsing expression




(lldb) expr [((id)0x7fe110297360) requireGestureToFail:((id)0x7fe10e842c00)]
error: no known method '-requireGestureToFail:'; cast the message send to the method's return type
error: 1 errors parsing expression

1 个答案:

答案 0 :(得分:1)

那么,为什么不将它转换为合适的类型呢?

exp -- [(UIGestureRecognizer *)address1 requireGestureToFail:(UIGestureRecognizer *)address2];

如果您想再玩一点并按照地址调用此方法(假设您仍然知道所有类型),请举例说明。

给出以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
    [[self window] setBackgroundColor:[UIColor purpleColor]];

    UIGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(windowTapped:)];
    [[self window] addGestureRecognizer:gr];
    [[self window] makeKeyAndVisible];
    return YES;
}

并在将手势识别器添加到窗口后立即设置制动点,您可以执行以下操作:

(lldb) po [self window]
<UIWindow: 0x7ffd2acaff50; frame = (0 0; 320 480); hidden = YES; gestureRecognizers = <NSArray: 0x7ffd2acb6930>; layer = <UIWindowLayer: 0x7ffd2aca8ac0>>

(lldb) image lookup -v -r -n "-\[UIGestureRecognizer view\]"
1 match found in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework/UIKit:
        Address: UIKit[0x00000000003c5c03] (UIKit.__TEXT.__text + 3946627)
        Summary: UIKit`-[UIGestureRecognizer view]`
         Module: file = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework/UIKit", arch = "x86_64"
         Symbol: id = {0x000050db}, range = [0x0000000107ee4c03-0x0000000107ee4c14), name="-[UIGestureRecognizer view]"

(lldb) exp UIView *(*$m)(id, SEL) = (UIView *(*)(id, SEL))0x0000000107ee4c03
(lldb) exp SEL $s = @selector(view)
(lldb) p gr
(UIGestureRecognizer *) $1 = 0x00007ffd2ad38c90
(lldb) exp -- $m((id)0x00007ffd2ad38c90, $s)
(UIView *) $2 = 0x00007ffd2acaff50
(lldb) po $2
<UIWindow: 0x7ffd2acaff50; frame = (0 0; 320 480); hidden = YES; gestureRecognizers = <NSArray: 0x7ffd2acb6930>; layer = <UIWindowLayer: 0x7ffd2aca8ac0>>

(lldb) 

基本上你要做的是,在内存中找到方法的地址(图像查找命令,-v开关),在适当的类型中创建一个临时的调试器变量(即$ m),然后使用2个隐藏的参数你必须传递给每个ObjC方法调用,调用此方法。正如您可以看到的那样,比较地址,您可以按照预期将原始窗口恢复原状。 希望有所帮助。