我在我的iOS应用程序中使用SQLite,当用户与UI交互时,我有很多保存/加载工作要做。这是一个问题,因为它使UI非常抖动和缓慢。
我尝试过在另一个线程中执行这些操作,但我认为这在SQLite中是不可能的。如果我这样做,我经常得到错误代码SQLITE_BUSY和SQLITE_LOCKED。
有没有办法在多线程中做到这一点而没有这些错误代码,或者我应该放弃SQLite?
发布于 2012-01-04 21:00:25
这是完全可能的,你只需要在你的后台线程中序列化对SQLite的访问。
我在this recent question上的回答应该会给你指明正确的方向。
正如在其他地方提到的,SQLite对于并发读取是很好的,但是对于写入是在数据库级别锁定的。这意味着如果你在不同的线程中读写,你会得到SQLITE_BUSY和SQLITE_LOCKED错误。
避免这种情况的最基本方法是在调度队列或并发为1的NSOperationQueue中序列化所有 DB访问(读取和写入)。由于此访问不是在主线程上发生的,因此您的UI不会受到影响。
这显然会阻止读取和写入重叠,但也会停止同时读取。目前还不清楚这是不是你能承受的性能损失。
如上所述初始化队列:
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
[backgroundQueue setMaxConcurrentOperationCount:1];然后,您可以在您认为合适的时候向队列中添加操作。
发布于 2012-01-05 02:01:03
将所有东西都放在一个专用的SQLite线程中,或者一次一个操作的操作队列都是很好的解决方案,特别是对于解决UI抖动的问题。另一种技术(可能对抖动没有帮助)是发现这些错误代码,然后简单地循环,重试更新,直到您获得成功的返回代码。
发布于 2012-02-04 01:18:00
将SQLite设置为WAL模式。那么读操作就不会被阻塞。不是这样写的--你需要序列化它们。有多种方法可以实现这一点。其中一个是由SQLite提供的- WAL钩子可以用来发信号通知下一次写入可以开始。
WAL模式通常会提高应用程序的性能。大多数事情都会快一点。读操作根本不会被阻塞。只有大型事务(几MB)才会减慢。一般没什么戏剧性的。
https://stackoverflow.com/questions/8727183
复制相似问题