0

我想从游戏中心服务器的回合制游戏中返回信息,这很好,但我想要使用异步方法获取的玩家别名:

[GKPlayer loadPlayersForIdentifiers:singleOpponentArray withCompletionHandler:^(NSArray *players, NSError *error) {

                GKPlayer *returnedPlayer = [players objectAtIndex:0];

                NSString *aliasToAdd = [NSString stringWithString:returnedPlayer.alias];
                NSString *idToAdd = [NSString stringWithString:returnedPlayer.playerID];
                NSDictionary *dictionaryToAddToAliasArray = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:aliasToAdd, idToAdd, nil] forKeys:[NSArray arrayWithObjects:@"alias", @"id", nil]];

                [self.aliasArray addObject:dictionaryToAddToAliasArray];


            }];

但是 UI 使用了这些信息并且它没有及时到达。如何使该方法在主线程上同步执行?

谢谢。

4

2 回答 2

1

任何与 UI 相关的代码都必须在主线程上执行。

如果您的应用必须等待异步调用返回,则首先禁用 UI。例如,设置userInteractionEnabled = NO在您的UIView.

然后,当异步方法返回时,重新启用UIView.

同时,显示某种活动指示器,例如UIActivityIndicatorView

当然,只有在您无法在后台执行任务的情况下才执行上述操作。永远不要不必要地阻塞 UI。我相信您当然已经知道这一点,但对于可能正在阅读本文的平台新手来说,值得重申。

要在主线程上调用,请使用NSObject'performSelectorOnMainThread方法的变体之一。dispatch_get_main_queue或者,或者,通过调用函数,使用主队列在 gcd 上排队。

于 2012-04-17T15:33:35.170 回答
0

您可以使用 GCD 函数执行此操作:

// Show an UILoadingView, etc

[GKPlayer loadPlayersForIdentifiers:singleOpponentArray
              withCompletionHandler:^(NSArray *players, NSError *error) {

    // Define a block that will do your thing
    void (^doTheThing)(void) = ^(void){
        // this block will be run in the main thread....
        // Stop the UILoadingView and do your thing here
    };

    // Check the queue this block is called in          
    dispatch_queue_t main_q = dispatch_get_main_queue();
    dispatch_queue_t cur_q = dispatch_get_current_queue();
    if (main_q != cur_q) {
        // If current block is not called in the main queue change to it and then do your thing
        dispatch_async(main_q, doTheThing);
    } else {
        // If current block is called in the main queue, simply do your thing
        doTheThing();
    }
}];
于 2012-04-17T15:53:50.123 回答