为了提高响应能力,一些使用FMDB在主线程上执行SQLite查询的同步方法被重写为异步,并通过-performSelectorInBackground:withObject:
在后台运行。但是,SQLite不是线程安全的,这些方法中的每一个最终都会调用-[FMDatabase open]
,从而降低整体性能。
因此,我为FMDB类编写了一个代理,它通过-forwardInvocation:
覆盖-[NSInvocation invokeWithTarget:]
以在一个特定线程上执行-performSelector:onThread:withObject:waitUntilDone:
。这解决了对-[FMDatabase open]
的调用过多的问题,但-forwardInvocation:
本身相当昂贵。
有没有一种很好的方法可以解决这个性能问题而无需重写所有调用FMDB方法的代码?
答案 0 :(得分:2)
您已发现问题:请勿拨打-performSelectorInBackground:withObject:
!我们无法保证它会做什么,但它可能不会做正确的事情。
如果您想要的是单个"数据库线程"对于后台操作,那么有几个选项:
-performSelector:onThread:...
。[[NSThread currentThread] threadDictionary]
中保存对数据库的线程本地引用。这有点乱,因为您几乎无法控制数据库何时消失。它也可能违反NSOperation合同(当操作完成时,你应该将线程恢复到原始状态。)