[英]NSInvocation to delay calling of method causing EXC_BAD_ACCESS
我正在尝试在游戏结束时显示一条消息,以显示玩家是否赢了。
以下是相关代码:
BOOL yes = YES;
NSString *winMessage = [NSString stringWithFormat:@"You win!"];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(endGameWithMessage:win:par:)]];
[inv setSelector:@selector(endGameWithMessage:win:par:)];
[inv setTarget:self];
[inv setArgument:&winMessage atIndex:2];
[inv setArgument:&yes atIndex:3]; //this is the win BOOL (0 and 1 are explained in the link above)
[inv setArgument:&parBool atIndex:4]; //this is the par BOOL
[inv performSelector:@selector(invoke) withObject:nil afterDelay:0.1f];
这是endGameWithMessage方法签名:
- (void)endGameWithMessage:(NSString*)message win:(BOOL)win par:(BOOL)parBool
尽管像这样直接调用代码(显然不会允许延迟)可以正常工作,但消息按预期显示,不会造成任何崩溃:
[self endGameWithMessage:@"You win!" win:YES par:parBool];
尝试使用NSInvocation会导致endGameWithMessage:方法的EXC_BAD_ACCESS崩溃。 这是否意味着我以错误的方式将值传递给方法调用?
这两段代码之间有两个区别:
使用字符串字面量@"You win!"
,另一个创建一个新的字符串对象。 字符串文字是静态分配的,而不是内存管理的,因此使用string参数进行的任何不正确的内存管理都会影响分配的对象,而不是字符串文字。
更重要的是, NSInvocation
是异步调用的,您并没有要求调用使用[inv retainArguments];
保留参数[inv retainArguments];
。 这意味着self
和winMessage
不会被调用保留,因为它应该异步使用它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.