我在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
答案 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方法调用,调用此方法。正如您可以看到的那样,比较地址,您可以按照预期将原始窗口恢复原状。 希望有所帮助。