Iphone 块内块=EXC\u坏访问
我有一个处理所有游戏中心逻辑的单例类:Iphone 块内块=EXC\u坏访问,iphone,ios,objective-c,xcode,Iphone,Ios,Objective C,Xcode,我有一个处理所有游戏中心逻辑的单例类: typedef void (^GameCenterCallbackFinishUpdating)(); - (void)getAllMatches:(GameCenterCallbackFinishUpdating)onComplete { [GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error) {
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)
我做错了什么 一些背景信息:块是对象,如果任何块nil
并且您尝试调用它们,则会使应用程序崩溃
在某个地方,不知何故,块onComplete
在调用它之前变为nil
。下面的if(…)
语句帮助您防止调用nil
指针,这样应用程序就不会崩溃
if (onComplete) onComplete();
感谢@holex和@Paul.s的解释。 我有过类似的情况,我将块作为方法参数发送(
completionHandler
)
有两种情况,或者我使用这个块,比如:
[MyClass sharedInstance] callX:@"abc" withCompletionHandler:^(NSString *response) {
if (response) {
//do something
}
}];
或者此块可以是nil
作为方法参数:
[MyClass sharedInstance] callX:@"abc" withCompletionHandler:nil];
在第二种情况下,当块作为方法参数传递nil
时,这导致EXC\u BAD\u访问oncompletion()。因此,当@holex声明块是对象时,如果任何块为nil,并且您试图调用它们,则会使应用程序崩溃。
一个if可以节省我很多时间
- (void)callX:(NSString *)xyz withCompletionHandler:(void (^)(NSString *response))completion
{
if (completion)
completion(something);
}
注:这种解释只适用于像我这样的书呆子如果(onComplete)onComplete()代码>这很有效。谢谢了解应用程序崩溃的原因仍然很有意思,因为块是对象,如果任何块nil
并且您试图调用它们,它就会使应用程序崩溃。在调用之前,该块在某个地方以某种方式变为nil
。if(…)
语句帮助您防止调用nil
指针,这样应用程序就不会崩溃。明白了!非常感谢:)如果您将您的答复作为答复提交,我将接受您的答复。我是否可以回答您是否接受?blocks are objects
语句似乎很不相关,您能否提供更多关于该信息与其余答复相关联的上下文信息?是的,它似乎非常相关,因为每个对象都可以是nil
指针,并且块是对象而不是函数或方法。你想知道关于这个街区的确切情况吗?这里的术语有点错误。对象不能是nil
,但可以有一个指向nil
的指针,因此这里更重要的事实是变量onComplete
没有指向任何对象。在这一点上,它的行为就像调用一个被赋值为NULL
的函数指针。Crash@Paul.s,是的,我同意你的看法,这个术语不太正确,因为正如你所说,指针可以是nil
。我想在这里告诉大家的是,许多开发人员相信块就像函数或方法一样,他们从不认为指向块的指针可以是nil
,他们必须在应用程序中管理这种情况。我只是想在这里展示一下这个重要的区别,苹果官方网站上有更多关于这些区块的专业文档。
- (void)callX:(NSString *)xyz withCompletionHandler:(void (^)(NSString *response))completion
{
if (completion)
completion(something);
}