【发布时间】:2014-04-08 15:48:28
【问题描述】:
首先,我想说的是,我真的很难在后台线程中配置和使用我的 SQLite DB,以免主线程被阻塞。
在网上某处找到一个小指南后,我决定使用 FMDB 包装器。
与数据库操作相关的所有方法都在同一个类中,这就是我遇到错误的地方:
我已经这样设置了静态变量:
static FMDatabaseQueue *_queue;
static NSOperationQueue *_writeQueue;
static NSRecursiveLock *_writeQueueLock;
然后在我的 init 方法中我有:
- (id)init {
self = [super init];
if (self) {
_queue = [FMDatabaseQueue databaseQueueWithPath:[self GetDocumentPath]];
_writeQueue = [NSOperationQueue new];
[_writeQueue setMaxConcurrentOperationCount:1];
_writeQueueLock = [NSRecursiveLock new];
}
return self;
}
这是给我错误的方法:
- (void)UpdateTime:(NSString *)idT :(int)userId {
[_writeQueue addOperationWithBlock:^{
[_writeQueueLock lock];
[_queue inDatabase:^(FMDatabase *dbase) {
AppDelegate *deleg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (![dbase executeUpdate:@"update orari set orario=datetime(orario, '? minutes') where nome=? and dataid>=? and idutente=?"
withArgumentsInArray:@[[NSNumber numberWithFloat:deleg.diff], deleg.nome, [NSNumber numberWithInt:deleg.idMed], [NSNumber numberWithInt: userId]]]) {
NSLog(@"error");
}
}];
[_writeQueueLock unlock];
}];
[_writeQueue addOperationWithBlock:^{
[_writeQueueLock lock];
[_queue inDatabase:^(FMDatabase *dbase) {
AppDelegate *deleg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (![dbase executeUpdate:@"UPDATE orari SET presa=1 where dataid=? and idutente=?"
withArgumentsInArray:@[[NSNumber numberWithInt:deleg.identific], [NSNumber numberWithInt: userId]]]) {
NSLog(@"error");
}
}];
[_writeQueueLock unlock];
}];
[self AddNotification];
}
这些是我得到的错误:
*** -[NSRecursiveLock dealloc]: lock (<NSRecursiveLock: 0xc38b350> '(null)') deallocated while still in use
DB Error: 5 "database is locked"
*** -[NSRecursiveLock unlock]: lock (<NSRecursiveLock: 0x13378d20> '(null)') unlocked when not locked
根据我阅读的指南,我认为对我的数据库的访问会被“序列化”,并且每次更新都会被添加到队列中并一次执行一个。
如您所见,我有很多关于这个主题的知识,所以任何帮助都将不胜感激。
【问题讨论】:
-
嗨 Aleph72,你有没有找到解决这个问题的方法?我遇到了类似的问题,并且还认为数据库进程已序列化。现在我收到 DB 错误:5“数据库已锁定。”
标签: ios multithreading sqlite fmdb