只释放一次实例资源?

时间:2012-09-24 05:50:29

标签: objective-c grand-central-dispatch

我需要在-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
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如果invalidate不需要线程安全,则可以执行

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

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

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

或者,您可以使用Synchronization方法之一,例如@synchronized

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