【问题标题】:NSInvocation to delay calling of method causing EXC_BAD_ACCESSNSInvocation 延迟调用导致 EXC_BAD_ACCESS 的方法
【发布时间】:2014-10-24 05:23:36
【问题描述】:

我正在尝试在游戏结束时显示一条消息,显示玩家是否获胜。

以下是相关代码:

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

【问题讨论】:

    标签: ios objective-c selector exc-bad-access nsinvocation


    【解决方案1】:

    这两段代码有两个区别:

    1. 一个使用字符串文字@"You win!",另一个创建一个新的字符串对象。字符串字面量是静态分配的,而不是内存管理的,因此使用字符串参数的任何不正确的内存管理都会影响分配的对象,而不是字符串字面量。

    2. 更重要的是,NSInvocation 是异步调用的,您没有要求调用保留带有[inv retainArguments]; 的参数。这意味着 selfwinMessage 不会被调用保留,因为它应该为了异步使用它们。

    【讨论】:

    • 感谢您的支持,尤其是发现 [inv retainArguments]; 的不足。您的假设是正确的,在设置我的所有参数后添加对 retainArguments 的调用修复了我的 EXC_BAD_ACCESS 崩溃,因为正如您所说,消息是使用 NULL 参数发送的。
    猜你喜欢
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    相关资源
    最近更新 更多