块内阻止= EXC_BAD_ACCESS

时间:2013-01-11 14:27:16

标签: iphone ios objective-c xcode

我有一个单例类来处理所有Game Center逻辑:

typedef void (^GameCenterCallbackFinishUpdating)();

- (void)getAllMatches:(GameCenterCallbackFinishUpdating)onComplete
{
    [GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error)
    {      
        //Do stuff here... 
        onComplete();
    }];
}

从另一个viewController我使用:

[[GameCenterHelper sharedHelper] getAllMatches:^{

    [self.myTableView reloadData]; 

}];

当我在应用程序中时效果很好,但是一旦我关闭应用程序(背景)然后再次启动它,我就会得到:

    onComplete();     ---- Thread 1: EXC_BAD_ACCESS (code=2, address=0xc)

我在这里做错了什么?

2 个答案:

答案 0 :(得分:9)

一些背景信息:这些块是对象,如果有任何块 nil ,并且您尝试调用它们,则会导致应用程序崩溃。

在某个地方以及在调用它之前,onComplete块变为nil。以下if (...)语句可帮助您阻止调用nil指针,因此应用程序不会崩溃。

if (onComplete) onComplete();

答案 1 :(得分:0)

感谢@holex和@ Paul.s的解释。 我有类似的情况,我发送块作为方法参数(completionHandler)。

- (void)callX:(NSString *)xyz withCompletionHandler:(void (^)(NSString *response))completion
{
    completion(something);
}

有两种情况我使用这个块,如:

[MyClass sharedInstance] callX:@"abc" withCompletionHandler:^(NSString *response) {
    if (response) {
        //do something
    }
}];

或此块可以是nil作为方法参数:

[MyClass sharedInstance] callX:@"abc" withCompletionHandler:nil];

在第二种情况下,当块传递nil作为方法参数时,这导致完成()上的EXC_BAD_ACCESS。因此@holex声明块是对象,如果任何块是nil并且你试图调用它们,它会崩溃应用程序。 单个if可以节省我的大部分时间

- (void)callX:(NSString *)xyz withCompletionHandler:(void (^)(NSString *response))completion
{
    if (completion)
        completion(something);
}

P.S:这个解释仅适用于像我这样的 NERDS 。 | 'L'|