0

我需要在一种-invalidate方法中保护一些代码以使串行队列无效,以便这些代码运行一次,就像dispatch_once在单例范式中一样。

我的直觉是:

@property(nonatomic, readonly, getter=isValid) BOOL valid;
@property(nonatomic) dispatch_queue_t serialQueue;
...
- (void)invalidate {
    if ([self isValid]){
        dispatch_sync(self.serialQueue, ^{
            if ([self isValid]) {
                _valid = NO;
                // relinquish resources here
            }
        });
        if (self.serialQueue) {
            dispatch_release (self.serialQueue);
        }
    }
}

-invalidate方法将被显式调用或由-dealloc. 而且我想确保资源将被放弃一次且仅一次。

这个实现是线程安全的吗?

dispatch_once以每个实例的方式实现块是更好的方法吗?

@property(nonatomic, readonly) dispatch_once_t invalidated;
...
- (void)invalidate {
    dispatch_once(&_invalidated, ^{
        dispatch_sync(logQueue, ^{
            // double check
            if (self.isValid) {
                self.valid = NO;
                // relinquish things
            }
        }
    }
}
4

1 回答 1

1

如果invalidate不需要是线程安全的,你可以这样做

- (void)invalidate {
    if ([self isValid]) {
        _valid = NO;
        // relinquish resources here
    }
}

因为设置_valid = NO已经保证该函数只被调用一次。

如果必须以线程安全的方式进行失效,事情会变得更复杂一些。你可以使用dispatch_once. 缺点是这真的只工作一次。因此,如果您稍后再次验证您的对象,则失效将不再起作用。

或者,您可以使用其中一种同步方法,例如@synchronized

- (void)invalidate {
    @synchronized(self) {
        if ([self isValid]) {
            _valid = NO;
            // relinquish resources here
        }
    }
}
于 2012-09-24T08:43:57.140 回答