当您应该从队列的角度考虑问题时,您正在从锁的角度考虑问题。给定一些共享的“资源”,您想要做的是这样的事情(未经测试)。这只是方法的草图,但它应该让你走上正确的轨道。您应该尽可能避免使用锁。
@implementation Resource
- (id)init {
...
// Assuming you are the only one who can possibly change the library
// See suspendQueue for related code
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@(resumeQueue:) ...
name:...thenoteification...];
// Always request things synchronously on the queue
- (Something *)somethingForStuff:(Stuff *)stuff {
__block Something *result;
dispatch_sync(self.queue, ^{
result = GetSomethingForStuffFromMe(stuff);
});
return result;
}
// Always change things asynchronously on the queue with a barrier
// And in your case, suspend the queue to lock it until done
- (void)setSomething:(Something *)something forStuff:(Stuff *)stuff {
dispatch_barrier_async(self.queue, ^{
SetSomethingForStuff(something, stuff);
[self suspendQueue];
});
}
// You'll need to think this through a little bit. It depends on your exact model.
// I'm using isSuspended really just as an error-check to make sure something
// hasn't gone wrong.
- (void)suspendQueue {
NSAssert(! self.isSuspended, @"In this example, I don't allow recursive suspension.");
[self.queue suspend];
self.suspended = YES;
}
// This code assumes you're the only one who can cause this notification.
// You may need to change things a little if that's not true
- (void)resumeQueue {
NSAssert(self.isSuspended, @"We should only ever see this notification if we caused it");
self.suspended = NO;
[self.queue resume];
}