Ras*_*nes 74 cocoa grand-central-dispatch ios4 ios
任何人都可以是很清楚的用例解释的目的dispatch_sync
在GCD
为?我无法理解我必须使用它的地点和原因.
谢谢!
Dav*_*har 77
当您想要执行块并等待结果时,可以使用它.
其中一个示例是您使用调度队列而不是锁来进行同步的模式.例如,假设您有一个共享的NSMutableArray a
,其访问由调度队列调解q
.后台线程可能会附加到数组(异步),而前台线程正在关闭第一个项目(同步):
NSMutableArray *a = [[NSMutableArray alloc] init];
// All access to `a` is via this dispatch queue!
dispatch_queue_t q = dispatch_queue_create("com.foo.samplequeue", NULL);
dispatch_async(q, ^{ [a addObject:something]; }); // append to array, non-blocking
__block Something *first = nil; // "__block" to make results from block available
dispatch_sync(q, ^{ // note that these 3 statements...
if ([a count] > 0) { // ...are all executed together...
first = [a objectAtIndex:0]; // ...as part of a single block...
[a removeObjectAtIndex:0]; // ...to ensure consistent results
}
});
Run Code Online (Sandbox Code Playgroud)
use*_*951 77
先了解它的兄弟 dispatch_async
//Do something
dispatch_async(queue, ^{
//Do something else
});
//Do More Stuff
Run Code Online (Sandbox Code Playgroud)
您dispatch_async
用来创建一个新线程.当你这样做时,当前线程不会停止.这意味着//Do More Stuff
可以在//Do something else
完成之前执行
如果你想让当前线程停止会发生什么?
你根本不使用派遣.只需正常编写代码即可
//Do something
//Do something else
//Do More Stuff
Run Code Online (Sandbox Code Playgroud)
现在,假设你想在一个不同的线程上做一些事情,然后等待并确保连续完成这些事情.
有很多理由这样做.例如,UI更新是在主线程上完成的.
这就是你使用的地方 dispatch_sync
//Do something
dispatch_sync(queue, ^{
//Do something else
});
//Do More Stuff
Run Code Online (Sandbox Code Playgroud)
在这里,你得到了//Do something
//Do something else
,并//Do More stuff
连续完成,即使//Do something else
在不同的线程完成.
通常,当人们使用不同的线程时,整个目的是让某些东西可以在不等待的情况下执行.假设您要下载大量数据,但希望保持UI流畅.
因此,很少使用dispatch_sync.但它就在那里.我个人从未使用过.为什么不要求使用dispatch_sync的示例代码或项目.
Cat*_*Man 25
dispatch_sync在语义上等同于传统的互斥锁.
dispatch_sync(queue, ^{
//access shared resource
});
Run Code Online (Sandbox Code Playgroud)
与...一样的工作
pthread_mutex_lock(&lock);
//access shared resource
pthread_mutex_unlock(&lock);
Run Code Online (Sandbox Code Playgroud)
David Gelhar没有说他的示例之所以有效,只是因为他悄悄创建了串行队列(在dispatch_queue_create 中传递了 NULL,等于 DISPATCH_QUEUE_SERIAL)。
如果你希望创建并发队列(以获得所有多线程能力),他的代码将导致崩溃,因为 NSArray 突变(addObject:) 在突变(removeObjectAtIndex:) 期间甚至访问错误(NSArray 范围超出界限)。在这种情况下,我们应该使用屏障来确保两个块运行时对 NSArray 的独占访问。它不仅在运行时排除对 NSArray 的所有其他写入,而且还排除所有其他读取,从而使修改安全。
并发队列的示例应如下所示:
NSMutableArray *a = [[NSMutableArray alloc] init];
// All access to `a` is via this concurrent dispatch queue!
dispatch_queue_t q = dispatch_queue_create("com.foo.samplequeue", DISPATCH_QUEUE_CONCURRENT);
// append to array concurrently but safely and don't wait for block completion
dispatch_barrier_async(q, ^{ [a addObject:something]; });
__block Something *first = nil;
// pop 'Something first' from array concurrently and safely but wait for block completion...
dispatch_barrier_sync(q, ^{
if ([a count] > 0) {
first = [a objectAtIndex:0];
[a removeObjectAtIndex:0];
}
});
// ... then here you get your 'first = [a objectAtIndex:0];' due to synchronised dispatch.
// If you use async instead of sync here, then first will be nil.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
49675 次 |
最近记录: |