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