FMDatabaselocking,在课堂上使用的最佳实践

我有一个应用程序的同步方法,我正在使用FMDatabase包装在本地存储SQLite数据。 当我把所有的查询在一个类中一切正常。 但是为了保持复杂性,我为同步的一部分添加了一些数据控制器类,但是当我这样做的时候,FMDatabase会给出'数据库locking'的错误,当我在数据类中添加一个新的连接时,一个参数。

现在我想在songleton中添加数据库连接,并想知道这是否是一个好习惯,以及如何将FMDatabase封装在单例类中。 任何帮助为什么这个问题发生,什么是解决这个问题的最好方法将不胜感激!

您还应该考虑使用FMDatabaseQueue,并将其粘贴在代码的某个共享区域中。 在multithreading上使用它也是安全的。

我不同意Tumtum的回答。 请阅读FMDB的文件 :

同时从多个线程使用FMDatabase的单个实例是一个坏主意。 每个线程创build一个FMDatabase对象总是可以的。 只是不要在线程之间共享一个实例,而且绝对不能同时在多个线程之间共享。 不好的事情最终会发生,你最终会得到一些东西崩溃,或者可能会得到一个例外,或者陨石可能会掉出天空,击中你的Mac Pro。 这会吸吮。

所以不要实例化一个FMDatabase对象并在多个线程中使用它。

相反,使用FMDatabaseQueue。 实例化一个FMDatabaseQueue并在多个线程中使用它。 FMDatabaseQueue对象将同步和协调跨多个线程的访问。

我已经用FMDatabase实现了singelton,使用下面的代码,这似乎已经解决了locking的数据库错误的问题。 不知道这是否是一个好的做法,但是这里是需要类似实现的每个人的代码。 我用这个教程在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

然后到处都需要访问我使用的数据库:

 DatabaseController* sharedDatabase = [DatabaseController sharedDatabase]; [sharedDatabase initDB]; //only the first time! In my case in my app delegate FMDatabase *db = [sharedDatabase getDB];