情况就是这样。 我有一个单例类调用DBManager与sqlite3。插入,删除,选择都是通过这个类完成的。 假设现在ClassA需要向表a插入一条记录,而ClassB需要从表a中选择一条记录。所以presudo代码是这样的。
Class A
[[DBManager getInstance] insertRecord:@"12345"];
Class B
-(void)processData{
Record r = [[DBManager getInstance] getRecord];
// working with record r. after that doing some layout update
[self.lbTitle setText:r.name];
}
因为在我的项目中,有4-5个类会访问db。所以有时数据库被锁定错误就是抛出而我的应用程序崩溃了。 我知道其中一个解决方案是使用GCD dispatch_async(CUSTOM_DB_QUEUE,block) 使用这些块来处理与db相关的所有代码。 但如果是这样,我还需要像这样修改B类。我是对的吗?
Class B
-(void)processData{
dispatch_async(CUSTOM_DB_QUEUE,{
[[DBManager getInstance] getRecord onRecordGot:^(Record* r) {
// working with record r. after that doing some layout update
dispatch_async(MAIN_QUEUE,{
[self.lbTitle setText:r.name];
)};
}];
)};
}
这种做法是否正确?所以我需要在DBManager中更改所有代码以使用块编码返回结果? 是否有任何简单的方法来排队保持DBManager类??
答案 0 :(得分:1)
有一种更好的方法。不要对调用DBManager
的代码进行任何更改。所有更改都应在DBManager
课程内进行。并且没有理由使用dispatch_async
。使用dispatch_sync
。
此代码保持不变:
Class A
[[DBManager getInstance] insertRecord:@"12345"];
Class B
-(void)processData{
Record r = [[DBManager getInstance] getRecord];
// working with record r. after that doing some layout update
[self.lbTitle setText:r.name];
}
在insertRecord:
方法中,您可以将其更改为:
- (void)insertRecord:(NSString *)record {
dispatch__barrier_sync(CUSTOM_DB_QUEUE, ^{
// original code to insert record
};
}
您的getRecord
方法变为:
- (Record *)getRecord {
__block Record *result = nil;
dispatch_sync(CUSTOM_DB_QUEUE, ^{
// original code that sets result
};
return result;
}
通过使用dispatch_sync
和dispatch_barrier_sync
,此代码允许对getRecord
进行任意数量的并发调用,但只允许调用insertRecord
。它还可确保在getRecord
运行时阻止对insertRecord:
的呼叫。
答案 1 :(得分:0)
要使其线程安全,可以使用pthread_mutex_t
作为全局实例。根据其用途锁定/解锁此互斥锁
e.g。
pthread_mutex_t *dbLock;
Class A
pthread_mutex_lock(dbLock);
[[DBManager getInstance] insertRecord:@"12345"];
pthread_mutex_unlock(dbLock);
Class B
-(void)processData{
pthread_mutex_lock(dbLock);
Record r = [[DBManager getInstance] getRecord];
// working with record r. after that doing some layout update
[self.lbTitle setText:r.name];
pthread_mutex_unlock(dbLock);
}