首先,我想说我在后台线程中尝试配置和使用我的SQLite数据库时遇到了不好的时间,因此主线程没有被阻止。
在互联网上找到一个小指南之后,我决定选择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
从我读过的指南中,我认为对我的数据库的访问将被“序列化”,并且每次更新都会被添加到队列中并一次执行一次。
正如您所看到的,我有很多东西可以学习这个主题,所以任何帮助都会非常感激。
答案 0 :(得分:0)
我可以看到你没有创建这个init调用的共享实例或单例实例
- (id)init {
self = [super init];
if (self) {
_queue = [FMDatabaseQueue databaseQueueWithPath:[self GetDocumentPath]];
_writeQueue = [NSOperationQueue new];
[_writeQueue setMaxConcurrentOperationCount:1];
_writeQueueLock = [NSRecursiveLock new];
}
return self;
}
这应该是一个单独调用,因为您将创建多个NSOperationQueue实例,这将使DB在多线程环境中易受攻击,尝试使用GCD或
对数据库进行单例调用static DBManager *sharedInstance = nil;
+(DBManager*)getSharedInstance{
if (!sharedInstance) {
sharedInstance = [[super allocWithZone:NULL]init];
_queue = [FMDatabaseQueue databaseQueueWithPath:[self GetDocumentPath]];
_writeQueue = [NSOperationQueue new];
[_writeQueue setMaxConcurrentOperationCount:1];
_writeQueueLock = [NSRecursiveLock new];
}
return sharedInstance;
}
它可能会解决您的问题,这是我第一次在这里回答,我是新手,所以请稍微宽容一点:)谢谢