0

我有一个简单的类,有两个 ivars, aNSMutableArray和 a BOOL。此类的对象在发送startShuffling消息时能够对数组中的元素进行洗牌。他们这样做直到收到stopShuffling消息。

为了使其工作,该startShuffling方法将布尔值设置为YES,然后while(self.isShuffling) { //... }在并发队列上分派混洗 ( ) 的代码块。将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:在改组循环终止其最后一回合时调用该方法是可能的(也许我错了?)。

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

4

1 回答 1

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 ... });
 }

或者其他的东西。

于 2012-08-07T21:33:16.973 回答