@synchronized块与GCD dispatch_async()

时间:2013-02-06 05:31:52

标签: ios objective-c grand-central-dispatch

基本上,我在NSDictionary中有一组数据,但为了方便起见,我设置了一些NSArray s,数据以几种不同的方式进行排序和过滤。数据将通过不同的线程(块)进入,我想确保一次只有一个块修改我的数据存储。

我在今天下午遇到了设置调度队列的麻烦,随后偶然发现了一篇关于@synchronized的帖子,这看起来几乎就像我想做的那样。

所以我现在所拥有的是......

// a property on my object
@property (assign) dispatch_queue_t matchSortingQueue;

// in my object init
_sortingQueue = dispatch_queue_create("com.asdf.matchSortingQueue", NULL);

// then later...
- (void)sortArrayIntoLocalStore:(NSArray*)matches
{
    dispatch_async(_sortingQueue, ^{
      // do stuff...
    });
}

我的问题是,我可以用以下内容替换所有这些吗?

- (void)sortArrayIntoLocalStore:(NSArray*)matches
{
    @synchronized (self) {
      // do stuff...
    };
}

......两者之间有什么区别?我应该考虑什么?

2 个答案:

答案 0 :(得分:5)

虽然功能差异对你来说可能并不重要,但这是你所期望的:如果你@synchronize那么你所在的线程会被阻止,直到它可以获得独占执行。如果你异步调度到一个串行调度队列,那么调用线程可以继续使用其他东西,无论你实际做什么,它总是会出现在同一个已知队列中。

因此,它们等同于确保一次只使用一个队列中的第三个资源。

如果您有一个资源可以通过主队列中的用户界面访问并且您想要改变它,那么调度可能是一个更好的主意。然后,您的用户界面代码不需要显式地@synchronize,从而非常自然地隐藏了对象内的线程方案的复杂性。如果你有一个可以在其他不同角色上触发其中一些变化的中央演员,调度也会更好。这将允许他们同时运作。

同步更紧凑,更容易进行调试。如果您正在做的事情往往是两三行而且您需要同步调度它,那么感觉创建队列的努力是不值得的 - 特别是当您考虑创建的隐含成本时一个块并将其移动到堆上。

答案 1 :(得分:4)

在第二种情况下,您将阻止调用线程,直到“do stuff”完成。使用队列和dispatch_async,您将不会阻止调用线程。如果从UI线程调用sortArrayIntoLocalStore,这将特别重要。