Ios NSInvocation延迟方法调用,导致EXC\u错误\u访问

Ios NSInvocation延迟方法调用,导致EXC\u错误\u访问,ios,objective-c,selector,exc-bad-access,nsinvocation,Ios,Objective C,Selector,Exc Bad Access,Nsinvocation,我试图在游戏结束时显示一条消息,显示玩家是否赢了 以下是相关代码: BOOL yes = YES; NSString *winMessage = [NSString stringWithFormat:@"You win!"]; NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(endGameWithMessage:win:par:)]

我试图在游戏结束时显示一条消息,显示玩家是否赢了

以下是相关代码:

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_访问崩溃。这是否意味着我以错误的方式将值传递给方法调用?

这两段代码之间有两个区别:

  • 一个使用字符串literal
    @“youwin!”
    ,另一个创建一个新的字符串对象。字符串文本是静态分配的,而不是内存管理的,因此任何使用字符串参数的错误内存管理都将影响分配的对象,而不是字符串文本

  • 更重要的是,
    NSInvocation
    是异步调用的,您没有要求调用使用
    [inv retainArguments]保留参数。这意味着调用不会保留
    self
    winMessage
    ,这是为了异步使用它们


  • 感谢您的支持,特别是您发现了[inv retainArguments]的不足;。您的假设是正确的,在设置所有参数后添加对retainArguments的调用修复了我的EXC_BAD_访问崩溃,因为正如您所说,消息是用空参数发送的。