这里我想做什么
我想在采取行动之前执行一个循环或类似的东西 到目前为止,我正在这样做
//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是一个从服务器广播的变量,会经常更改。基于用户交互的更改,而另一个用户将等待将播放哪些卡。
简而言之,在等待广播变量到来时我该怎么办?有什么建议吗?感谢
答案 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];