0

这是我想做的

到目前为止,我想在执行操作之前执行一个循环或类似的操作,我正在这样做

//check if it's multiplayer mode
if ([PlayerInfo instance].playingMultiplayer == YES)
{
   //no cards has been played
   //the while and NSRunLoop combination seems harsh
   while ([PlayerInfo instance].cardsPlayed == NULL) 
   {
      [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
   }
   //after the "loop thing" done, execute this method
   //take out cards with the broadcasted cardsPlayed, it's event based
   [self takeOutCards:[PlayerInfo instance].cardsPlayed];
}
//single player, don't bother this
else
    {
       //AI logic, select possible best cards
       NSArray * bestCards = [playerLogic selectBestMove];
       [self takeOutCards:bestCards];
    }

这看起来是一种不好的做法。

顺便说一下,[PlayerInfo instance].cardsPlayed 是一个从服务器广播的变量,会经常更改。基于用户交互的更改,而另一个用户将等待将播放哪些牌。

简而言之,在等待广播变量到来时我应该怎么做?有什么建议吗?谢谢

4

1 回答 1

1

您的应用程序已经运行了一个事件循环,并且它应该已经在用户操作之间以及正在检查网络的新状态时处于空闲状态。您要做的是在触发条件时生成一个事件,以便应用程序做出反应。

最简单的方法是在条件发生时发布通知(在应用程序内)。像这样的东西:

// just guessing about your PlayerInfo here, and assuming ARC

@property (nonatomic, strong) NSArray *cardsPlayed;
@synthesize cardsPlayed = _cardsPlayed;

// replace the synthesized setter with one that does the set and checks for
// the condition you care about.  if that condition holds, post a notification
//
- (void)setCardsPlayed:(NSArray *)cardsPlayed {
    _cardsPlayed = cardsPlayed;

    // is the condition about an array that's nil or empty?  guessing 'either' here...
    if (!_cardsPlayed || !_cardsPlayed.count) {
        [[NSNotificationCenter defaultCenter] 
            postNotificationName:@"CardsPlayedDidBecomeEmpty" object:self];
   }
}

然后,在初始化关心条件的对象时(您在问题中提出该循环的位置)......

    [[NSNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(cardsPlayedEmpty:)
               name:@"CardsPlayedDidBecomeEmpty" object:nil];

这将导致 cardsPlayedEmpty: 在条件成立时被调用。它应该有这样的签名:

- (void)CardsPlayedDidBecomeEmpty:(NSNotification *)notification {
}

编辑-我认为您修改后的问题是您想在检查服务器状态之前暂停。您可以使用 performSelector:withObject:afterDelay: ...

- (void)getRemoteState {

    NSURLRequest = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        // here, handle the response and check the condition you care about
        // post NSNotification as above here
                       }];
}

// now the code you're trying to write ...

if ([PlayerInfo instance].playingMultiplayer == YES) {

    // give other players a chance to play, then check remote state
    // this will wait 20 seconds before checking
    [self performSelector:@selector(getRemoteState) withObject:nil afterDelay:20.0];
于 2012-11-28T03:26:03.817 回答