Ios 是否可以从其他类访问fmdatabaseQueues
我有一个应用程序,它使用FMDatabase在用户收集的数据中插入数据,还有一些是从web下载的。由于对数据库的同时请求太多,我目前正遇到一些崩溃 我想浏览我的应用程序并将FMDatabaseQueue添加到我的所有db操作中,但是我需要整个应用程序的一个队列,因为我有从web下载数据并将其插入db的后台类,并且我必须访问数据库以填充用户看到的UITableView 所以我的问题是,您能创建一个在所有类中都引用的静态FMDatabaseQueue吗 我的第二个问题是,我的查询当前的格式是否为Ios 是否可以从其他类访问fmdatabaseQueues,ios,multithreading,sqlite,fmdb,Ios,Multithreading,Sqlite,Fmdb,我有一个应用程序,它使用FMDatabase在用户收集的数据中插入数据,还有一些是从web下载的。由于对数据库的同时请求太多,我目前正遇到一些崩溃 我想浏览我的应用程序并将FMDatabaseQueue添加到我的所有db操作中,但是我需要整个应用程序的一个队列,因为我有从web下载数据并将其插入db的后台类,并且我必须访问数据库以填充用户看到的UITableView 所以我的问题是,您能创建一个在所有类中都引用的静态FMDatabaseQueue吗 我的第二个问题是,我的查询当前的格式是否为
FMResultset *result= [[databaseModel sharedInstance]executeQuery:@"SELECT * FROM TABLE1"];
if(![result next]){
[[databaseModel sharedInstance]executeUpdate:@"UPDATE TABLE1 SET foo=bar where 1;"];
那么这会变成什么呢
[dbQueue inDatabase(FMdatabase db) ^{ //dbQueue is declared statically
FMResultset *result= [[databaseModel sharedInstance]executeQuery:@"SELECT * FROM TABLE1"];
if(![result next]){
[[databaseModel sharedInstance]executeUpdate:@"UPDATE TABLE1 SET foo=bar where 1;"];
}
}];
如果您有任何建议、进一步阅读的指南或博客,我们将不胜感激,提前感谢mark有几种方法可以通过不同的类访问您的
FMDatabaseQueue
。可以是单例,将其作为应用程序委托的属性(您可以通过从[[UIApplication sharedApplication]delegate]
检索应用程序的委托来检索),也可以在第一个视图控制器中创建并传递它
就个人而言,我倾向于单例对象,比如说DatabaseManager
。@接口
文件可能如下所示:
//
// DatabaseManager.h
// Database Manager Example
//
// Created by Robert Ryan on 6/24/13.
// Copyright (c) 2013 Robert Ryan. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "FMDatabaseQueue.h"
@interface DatabaseManager : NSObject
@property (nonatomic, strong) FMDatabaseQueue *databaseQueue;
+ (instancetype)sharedManager;
@end
//
// DatabaseManager.m
// Database Manager Example
//
// Created by Robert Ryan on 6/24/13.
// Copyright (c) 2013 Robert Ryan. All rights reserved.
//
#import "DatabaseManager.h"
@implementation DatabaseManager
+ (instancetype)sharedManager
{
static id sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init
{
self = [super init];
if (self) {
_databaseQueue = [[FMDatabaseQueue alloc] initWithPath:[self databasePath]];
}
return self;
}
- (NSString *)databasePath
{
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
return [docsPath stringByAppendingPathComponent:@"test.sqlite"];
}
@end
然后,当您想要使用这个单例时,包括DatabaseManager.h
头文件,您可以执行如下操作:
#import "ViewController.h"
#import "DatabaseManager.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
DatabaseManager *databaseManager = [DatabaseManager sharedManager];
[databaseManager.databaseQueue inDatabase:^(FMDatabase *db) {
FMResultSet *result = [db executeQuery:@"SELECT * FROM TABLE1"];
if (!result) {
NSLog(@"%s: executeQuery error: %@", __FUNCTION__, [db lastErrorMessage]);
return;
}
while ([result next]) {
// do whatever you want with the results
}
[result close];
}];
}
// the rest of your code here
@end
简而言之,您希望停用databaseModel
singleton(顺便说一句,按照惯例,您的类名应该以大写字母开头),并为FMDatabaseQueue
对象创建一个singleton。然后,在inDatabase
块中,您可以只引用db
参数,而不引用任何外部数据库对象
注意,我已将我的singleton设置为
NSObject
子类,而FMDatabaseQueue
是该类的公共属性。你有很多选择。例如,您还可以将singleton设置为FMDatabaseQueue
子类本身(有点像您显然对当前的databaseModel
对象所做的那样,它似乎是FMDatabase
子类)。或者,根据我个人的偏好,我实际上将FMDatabaseQueue
对象作为我的DatabaseManager
的私有属性,并从控制器中删除任何FMDB代码,等等。我将所有FMDB代码保存在这个新的单例中,或者可能的话,保存在我的模型对象中。当你有大项目时,你可能不希望SQL语句到处乱扔。就我个人而言,我认为FMDB代码和SQL语句是一个实现细节,应该封装在DatabaseManager
类或可能的模型类中。这样一来,大型项目的管理就容易多了。但是你可以想怎么做就怎么做。Rob,谢谢你的回答,这样我就可以清楚地知道我不需要打开或关闭数据库了?@MarkGilchrist你不必打开它。使用[FMDatabaseQueue databaseQueueWithPath:path]
或[[FMDatabaseQueue alloc]initWithPath:path]
创建队列,然后只需发出inDatabase
方法即可。FMDatabaseQueue
将为您打开数据库。好的,我已经更改了所有代码,它工作正常,非常感谢您的帮助