8

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

今天下午我遇到了设置调度队列的麻烦,然后偶然发现了一篇关于@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...
    };
}

......无论如何,两者之间有什么区别?我应该考虑什么?

4

2 回答 2

6

尽管功能差异对您来说可能并不重要,但这正是您所期望的:如果您这样做,那么您@synchronize所在的线程将被阻塞,直到它可以独占执行。如果您异步调度到串行调度队列,那么调用线程可以继续处理其他事情,无论您实际在做什么,都将始终发生在同一个已知队列上。

因此,它们等效于确保一次仅从一个队列中使用第三种资源。

例如,如果您有一个可由用户界面从主队列访问的资源,并且您想改变它,那么调度可能是一个更好的主意。然后你的用户界面代码不需要显式地@synchronize隐藏你的线程方案的复杂性在对象中很自然。如果您有一个可以在其他不同参与者上触发其中一些更改的中心参与者,那么调度也是一个更好的主意;这将允许它们同时运行。

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

于 2013-02-06T05:51:50.427 回答
4

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

于 2013-02-06T05:45:52.587 回答