问题描述
我有一个app的同步方法,我正在构建使用FMDatabase包装器在本地SQLite中存储数据。当我把所有查询都放在一个类中时,一切正常。然而,为了保持复杂性,我为同步的部分添加了一些数据控制器类,但是当我这样做时,FMDatabase给出了数据库锁定错误,无论是在数据类中添加新连接还是在初始数据库连接中发送时一个参数。
I have a sync method for an app I'm building storing data in SQLite locally, using the FMDatabase wrapper. When I put all the queries in one class everything works fine. However to maintain complexity I added some data controller classes for parts of the sync, but when I do so FMDatabase gives 'database locked' errors, both when I add a new connection in a data class and when I send along the initial database connection as a parameter.
现在我想在songleton中添加数据库连接,并想知道这是不是很好的做法以及如何将FMDatabase包装在单例类中。任何关于问题发生的原因以及解决这个问题的最佳方法的帮助将不胜感激!
Now I was thinking to add the database connection in a songleton, and was wondering if that is good practice and how I wrap FMDatabase in a singleton class. Any help on why the issue happens and what's the best way of working around this would be greatly appreciated!
推荐答案
我已经实施了使用以下代码的带有FMDatabase的singelton,它似乎解决了锁定的数据库错误的问题。不确定这是不是很好的做法,但这里是需要类似实现的每个人的代码。我在singeletons上使用了。
I've implemented a singelton with an FMDatabase using the following code, which seems to have resolved the issue with the locked Database error. Not sure if this is good practice, but here's the code for everyone that needs a similar implementation. I used this tutorial on singeletons.
单身人士:
DatabaseController.h:
#import <Foundation/Foundation.h>
#import "FMDatabase.h"
@interface DatabaseController : NSObject
@property (strong, nonatomic) FMDatabase *db;
+ (id)sharedDatabase;
- (void)initDB;
- (FMDatabase *)getDB;
@end
DatabaseController.m:
#import "DatabaseController.h"
@implementation DatabaseController
static DatabaseController *sharedDatabase = nil;
// Get the shared instance and create it if necessary.
+ (DatabaseController *)sharedDatabase {
if (sharedDatabase == nil) {
sharedDatabase = [[super allocWithZone:NULL] init];
}
return sharedDatabase;
}
- (void)initDB {
NSString *databaseName = @"MyDatabase.db";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
NSString *databasePath = [documentDir stringByAppendingPathComponent:databaseName];
_db = [FMDatabase databaseWithPath:databasePath];
if (![_db open])
NSLog(@"Database problem");
}
// Return database instance
- (FMDatabase *)getDB {
return _db;
}
// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init {
self = [super init];
if (self) {
// Work your initialising magic here as you normally would
}
return self;
}
// Equally, we don't want to generate multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
return self;
}
@end
使用singelton
然后我需要访问我使用的数据库:
Then everywhere I need to acces the database I use:
DatabaseController* sharedDatabase = [DatabaseController sharedDatabase];
[sharedDatabase initDB]; //only the first time! In my case in my app delegate
FMDatabase *db = [sharedDatabase getDB];
这篇关于FMDatabase已锁定,是课堂内使用的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!