除非另有说明,否则是否所有iOS GameCenter回调都在主线程上执行?

我从各种来源阅读了很多关于GameCenter的内容……特别是Apple的文档以及一些关于实现GameCenter多人游戏的Apress书籍,但我无法找到一个明确的答案,我是否可以信任回调,例如matchmakerViewController:didFindMatch或match :didReceiveData:fromPlayer(仅举几个例子)总是出现在主线程上.

有时候在Apple的文档中,他们明确地说一个调用将始终在主线程上,但是对于每个函数都清楚它们并不一致.

Apress的书籍往往对线程完全偏执,所以他们使用dispatch_async来确保它最终在主线程上.

我的问题很简单……除非苹果公司另有说法,否则我可以相信,这些电话将在主线上,或者我需要像Apress书一样偏执.

(请不要回答’只是到处都是偏执,不要担心’)

最佳答案 我一直在研究同样的事情,Apple发现的关于这个问题的最明确的评论是在他们提供的GKTapper示例应用程序中的GameCenterManager.m文件头部的评论中(
https://developer.apple.com/library/ios/samplecode/gktapper/Listings/Classes_GameCenterManager_m.html):

“GameCenter does not guarantee that callback blocks will be execute on the main thread. As such, your application needs to be very careful in how it handles references to view controllers. If a view controller is referenced in a block that executes on a secondary queue, that view controller may be released (and dealloc’d) outside the main queue.”

建议的解决方案(并在样本中实施)如下所示.
虽然GameKit自代码发布以来已经经历了几个新版本,但我还没有看到任何声明这不再是问题,所以我将在我自己的代码中实现这个解决方案.

- (void) callDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err
{
    assert([NSThread isMainThread]);
    if([delegate respondsToSelector: selector])
    {
        if(arg != NULL)
        {
            [delegate performSelector: selector withObject: arg withObject: err];
        }
        else
        {
            [delegate performSelector: selector withObject: err];
        }
    }
    else
    {
        NSLog(@"Missed Method");
    }
}    



- (void) callDelegateOnMainThread: (SEL) selector withArg: (id) arg error: (NSError*) err
{
    dispatch_async(dispatch_get_main_queue(), ^(void)
    {
       [self callDelegate: selector withArg: arg error: err];
    });
}

我强烈建议下载GKTapper示例应用程序,并在潜入并实现自己的GameKit解决方案之前使用它来查看它是如何工作的.

点赞