????????最近在一些簡書或博客中看到一些使用GCD來保證操作NSMutableArray的多線程安全性烛芬,甚至在高質(zhì)量一書中也提到了零截,代碼如下:
// 創(chuàng)建一個并發(fā)隊列
@interfacetestCurrentString :NSObject
- (NSString*)getSomeString;
- (void)setSomeString:(NSString*)xxx;
@end
@implementationtestCurrentString
{
? ? dispatch_queue_t conCurrent;
? ? NSString*someString;
}
- (instancetype)init {
? ? self? = [superinit];
? ? if(self) {
? ? ? ? conCurrent = dispatch_queue_create("testString", DISPATCH_QUEUE_CONCURRENT);
? ? ? ? someString=@"1";
? ? }
? ? return self;
}
- (NSString*)getSomeString {
? ? __blockNSString*localString;
? ? dispatch_sync(conCurrent, ^{
? ? ? ? localString =someString;
? ? ? ? NSLog(@"current thread is %p", [NSThread currentThread]);
? ? });
? ? returnlocalString;
}
- (void)setSomeString:(NSString*)xxx {
? ? dispatch_barrier_async(conCurrent, ^{
? ? ? ? someString= xxx;
? ? });
}
@end
? ? testCurrentString *str = [[testCurrentString alloc] init];
? ? for(int? i =0; i <10; ++i) {
? ? ? ? dispatch_async(conQueue, ^{
? ? ? ? ? ? NSLog(@"在%@進(jìn)行第%@個操作,線程:%p", [[NSDate date] description], str.getSomeString, [NSThread currentThread]);
? ? ? ? });
? ? }
疑惑:1. 如果是上文說的逃呼,getSomeString里用了dispatch_sync拄养,那么不是真正的并發(fā)讀取嗎轿衔?因為我們知道sync永遠(yuǎn)只有在當(dāng)前線程執(zhí)行完才執(zhí)行后續(xù)的操作腮鞍,同時只在一個線程里執(zhí)行
? ? ? ? ? ?2. 如果改成dispatch_async,有什么問題枣耀?
說明:
? ? ? ? ?再回答上面的問題前霉晕,說一個現(xiàn)象:
dispatch_queue_tserialQueue = dispatch_queue_create("serial.queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_tglobalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
dispatch_sync(globalQueue, ^{
BOOLres1 = [NSThreadisMainThread];
BOOLres2 = dispatch_get_specific("key") !=NULL;
NSLog(@"is main thread: %zd --- is main queue: %zd", res1, res2);})
這段代碼res1執(zhí)行輸出是多少?true or false?
答案:輸出是 true捞奕,為什么牺堰?不是應(yīng)該執(zhí)行g(shù)lobalQueue里的一個子線程嗎?
不是的颅围,蘋果為了減少線程切換伟葫,而做了優(yōu)化,只在當(dāng)前線程執(zhí)行院促,所以判斷的話筏养,就輸出true了
好了,在理解了這個現(xiàn)象后常拓,我在回答上面的問題渐溶,如果改成async,那么怎么返回值呢弄抬?茎辐?
上面的sync和dispatch_barrier_async 只是保證讀讀不互斥,而讀寫互斥掂恕,所以外部在用async來讀取的時候拖陆,就是并發(fā)讀取
而寫的時候,就能做到寫的時候不讓讀懊亡,直到寫完依啰,做到了讀寫的多線程的安全