Objective-C:同步代码

时间:2012-08-07 21:21:10

标签: objective-c synchronization nsmutablearray grand-central-dispatch

我有一个简单的课程,有两个ivars,NSMutableArrayBOOL。当发送startShuffling消息时,此类的对象能够在数组中混洗元素。他们这样做,直到收到stopShuffling消息。

为了使其工作,startShuffling方法将布尔值设置为YES,然后调度在并发队列上混洗(while(self.isShuffling) { //... }的代码块。{{1}将布尔值设置为stopShuffling,以便洗牌过程在下一个循环转弯时终止。

这是界面:

NO

实施:

@interface MyClass : NSObject <NSCoding> {
@private
    NSMutableArray *elements_;
    __block BOOL isShuffling_;
}

@property(readonly) BOOL isShuffling;

-(void)startShuffling;
-(void)stopShuffling;

@end

我的类符合@implementation MyClass @synthesize isShuffling = isShuffling_; -(void)startShuffling { if(self.isShuffling) { return; } isShuffling_ = YES; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ while(isShuffling_) { // code that shuffles, one element by turn NSUInteger elementIndex = arc4random() % [elements_ count]; id c = [[elements_ objectAtIndex:elementIndex] retain]; [elements_ removeObjectAtIndex:elementIndex]; [elements_ insertObject:c atIndex:[elements_ count]]; [c release]; } }); } -(void)stopShuffling { isShuffling_ = NO; } @end 协议,即使对象正在改组,我也不想中止编码。相反,我希望我的对象停止改组然后编码自己。所以我编写了这种编码方法:

NSCoding

最后,我的问题在这里 我认为有可能在洗牌循环结束其最后一个转弯时调用-(void)encodeWithCoder:(NSCoder *)aCoder { if(self.isShuffling) { [self stopShuffling]; } [aCoder encodeObject:elements_ forKey:kIVPCodingKeyMyClassElements]; } 方法(也许我错了?)。

有什么方法可以让encodeObject:forKey:方法之后调用等待最后一轮的洗​​牌循环终止?

1 个答案:

答案 0 :(得分:2)

是的,调用encodeObject:forKey:方法时,shuffle代码可能仍在运行。

通常,您不希望将一些随机块调度到执行很长时间的队列中,可能永远存在。你想把工作分解成工作块。你的答案就在那里。

类似的东西:

 - (void)shuffleAndCheck
 {
    if (stillShuffling) {
         dispatch_async(globalConcurrentQueue, ^{
              dispatch_apply(shuffleQueue, ^{... shuffle one card code ...});
         });
         dispatch_async(shuffleQueue, ^{ [self shuffleAndCheck]; });
    }
 }

 - (void) startShuffling
 {
    if (stillShuffling) return;
    stillShuffling = YES;
    [self shuffleAndCheck];
 }

 - (void) stopShuffling
 {
    stillShuffling = NO;
    dispatch_async(shuffleQueue, ^{ ... encode stuff here ... });
 }

或其他什么。