异步过程给我带来麻烦

时间:2012-04-17 15:25:12

标签: iphone objective-c ios multithreading grand-central-dispatch

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

[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使用这些信息并没有及时到达。如何在主线程上同步执行该方法?

感谢。

2 个答案:

答案 0 :(得分:1)

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

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

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

在此期间,显示某种活动指标,例如UIActivityIndicatorView

当然,只有在无法在后台执行任务的情况下才能执行上述操作。绝不会不必要地阻止UI。我肯定你已经知道了,但是对于那些可能正在读这篇文章的平台新手来说,这是值得重述的。

要在主线程上调用,请使用NSObject的{​​{1}}方法的变体之一。或者,通过调用performSelectorOnMainThread函数,使用主队列将其排在gcd上。

答案 1 :(得分: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();
    }
}];