假设我创建了一个对象myObject
,在某些时候我希望它被锁定,直到我收到通知。我收到通知后,我想解锁它。这可以使用GCD完成,还是必须使用锁或什么?谢谢!
编辑:
所以这是我正在努力解决的确切问题。
我有一个帖子正在向ALAssetsLibrary
写照片。
用户界面正在使用ALAssets
来显示图书馆中的照片。
我的问题是:writeImageDataToSavedPhotosAlbum
更改了库,导致所有ALAssets
无效,所以如果我的第二个线程正在从库中加载照片,它可能会失败(并且经常会)。我读到解决这个问题的唯一方法是在ALAssetsLibraryChangedNotification
之后加载,所以我从写入它的那一刻起到收到通知的那一刻我都试图使库无法访问。
答案 0 :(得分:0)
当您考虑队列时,您正在考虑锁定方面的问题。你想要做的就是这样(未经测试),给定一些共享的“资源”。这只是该方法的草图,但它应该让你走上正确的轨道。你应该尽可能避免锁定。
@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];
}