我有一个单例类来处理所有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)
我在这里做错了什么?
答案 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'|