0

シングルトン パラダイムの-invalidateように、これらのコードが 1 回実行されるように、メソッドでシリアル キューを無効にするコードを保護する必要があります。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。欠点は、これが実際に 1 回しか機能しないことです。したがって、後でオブジェクトを再度検証すると、無効化は機能しなくなります。

または、次のような同期方法のいずれかを使用でき@synchronizedます。

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