先說明今天的疑問
在做FMDB的本地存儲,查詢了解到,F(xiàn)MDB在多線程訪問數(shù)據(jù)庫,針對線程安全上,使用過了FMDatabaseQueue類進(jìn)行實(shí)例化數(shù)據(jù)庫。FMDatabaseQueue有兩個(gè)常用方法:
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block
和
- (void)inDatabase:(void (^)(FMDatabase *db))block
這兩個(gè)方法實(shí)際上都是通過GCD創(chuàng)建一個(gè)串行隊(duì)列,這樣,每次的數(shù)據(jù)庫操作,都在這個(gè)串行隊(duì)列中完成,達(dá)到線程安全的目的。
到此都沒有任何毛病
但是我自己的毛病出來了
“既然FMDB是自己創(chuàng)建的queue,那也就是在主線程外的其他線程中執(zhí)行的,就不用在做后臺操作數(shù)據(jù)庫的處理了。”這是我想的。
由于對線程隊(duì)列的理解不夠透徹,在我的意識里,GCD中,除去main_queue之外,用戶通過dispatch_queue_create創(chuàng)建的隊(duì)列(包括同步和異步隊(duì)列),GCD給我們的全局隊(duì)列dispatch_get_global_queue,都是不會再主線程去執(zhí)行任務(wù)的。
簡化就是,我以為(注意,是“我以為”)只有main_queue才會在主線程執(zhí)行任務(wù),其他的隊(duì)列都是在其他線程執(zhí)行任務(wù)。
NSError
我上邊說的我以為,我意識的都是錯(cuò)的。
任務(wù)在哪個(gè)線程執(zhí)行,與隊(duì)列關(guān)系不大(也是有一定關(guān)系,后面說),主要看這個(gè)任務(wù)代碼,是同步執(zhí)行還是異步執(zhí)行。
queue只是一個(gè)管理任務(wù)的數(shù)組,他所能控制的是任務(wù)的順序執(zhí)行還是一起執(zhí)行
同步異步才能決定我們是否開啟新線程,上圖說比較清晰
這里就不一一列舉各種情況了,文章最后會給出上邊三張圖的原著,下邊只是簡單的截一個(gè)自己測試的圖
最后感謝 http://www.lxweimin.com/p/414b8e91e021 作者