循环直到变量发生变化

时间:2012-11-28 02:37:36

标签: objective-c ios events loops

这里我想做什么

我想在采取行动之前执行一个循环或类似的东西 到目前为止,我正在这样做

//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实例] .cardsPlayed是一个从服务器广播的变量,会经常更改。基于用户交互的更改,而另一个用户将等待将播放哪些卡。

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

1 个答案:

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