我在我的iOS应用程序中使用SQLite,并且在用户与UI交互时需要进行大量的保存/加载操作。这是一个问题,因为它使UI非常抖动和缓慢。
我尝试在另一个线程中执行操作,但我认为在SQLite中不可能实现。如果我这样做,我会经常收到SQLITE_BUSY和SQLITE_LOCKED错误代码。
是否有一种在多线程中完成此操作而不出现这些错误代码的方法,或者我应该放弃SQLite?
我在我的iOS应用程序中使用SQLite,并且在用户与UI交互时需要进行大量的保存/加载操作。这是一个问题,因为它使UI非常抖动和缓慢。
我尝试在另一个线程中执行操作,但我认为在SQLite中不可能实现。如果我这样做,我会经常收到SQLITE_BUSY和SQLITE_LOCKED错误代码。
是否有一种在多线程中完成此操作而不出现这些错误代码的方法,或者我应该放弃SQLite?
完全可以实现,只需要在后台线程中对SQLite的访问进行串行化。
我在这篇最近的问题上的回答应该能指导您正确地方向。
正如其他地方提到的,SQLite对于并发读取是可以的,但对于写入则在数据库级别上加锁。这意味着如果您在不同的线程中进行读取和写入,您将获得SQLITE_BUSY和SQLITE_LOCKED错误。
避免这种情况的最基本方法是将所有的DB访问(读和写)串行化,可以使用调度队列或具有1个并发的NSOperationQueue
。由于此访问不在主线程上进行,因此不会影响您的UI。
这显然会阻止读取和写入重叠,但也会阻止同时读取。目前尚不清楚这是否会对性能造成影响。
要初始化如上所述的队列:
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
[backgroundQueue setMaxConcurrentOperationCount:1];
把所有操作放在一个专用的SQLite线程中,或者使用一次只执行一个操作的操作队列是很好的解决方案,特别是为了解决您的UI卡顿问题。另一种技术(可能对抖动没有帮助)是发现那些错误代码,然后简单地循环重试更新,直到获得成功的返回代码。