先说明今天的疑问
在做FMDB的本地存储,查询了解到,FMDB在多线程访问数据库,针对线程安全上,使用过了FMDatabaseQueue类进行实例化数据库。FMDatabaseQueue有两个常用方法:
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block
和
- (void)inDatabase:(void (^)(FMDatabase *db))block
这两个方法实际上都是通过GCD创建一个串行队列,这样,每次的数据库操作,都在这个串行队列中完成,达到线程安全的目的。
到此都没有任何毛病
但是我自己的毛病出来了
“既然FMDB是自己创建的queue,那也就是在主线程外的其他线程中执行的,就不用在做后台操作数据库的处理了。”这是我想的。
由于对线程队列的理解不够透彻,在我的意识里,GCD中,除去main_queue之外,用户通过dispatch_queue_create创建的队列(包括同步和异步队列),GCD给我们的全局队列dispatch_get_global_queue,都是不会再主线程去执行任务的。
简化就是,我以为(注意,是“我以为”)只有main_queue才会在主线程执行任务,其他的队列都是在其他线程执行任务。
NSError
我上边说的我以为,我意识的都是错的。
任务在哪个线程执行,与队列关系不大(也是有一定关系,后面说),主要看这个任务代码,是同步执行还是异步执行。
queue只是一个管理任务的数组,他所能控制的是任务的顺序执行还是一起执行
同步异步才能决定我们是否开启新线程,上图说比较清晰
这里就不一一列举各种情况了,文章最后会给出上边三张图的原著,下边只是简单的截一个自己测试的图
最后感谢 //www.greatytc.com/p/414b8e91e021 作者