Ios 是否可以从其他类访问fmdatabaseQueues

Ios 是否可以从其他类访问fmdatabaseQueues,ios,multithreading,sqlite,fmdb,Ios,Multithreading,Sqlite,Fmdb,我有一个应用程序,它使用FMDatabase在用户收集的数据中插入数据,还有一些是从web下载的。由于对数据库的同时请求太多,我目前正遇到一些崩溃 我想浏览我的应用程序并将FMDatabaseQueue添加到我的所有db操作中,但是我需要整个应用程序的一个队列,因为我有从web下载数据并将其插入db的后台类,并且我必须访问数据库以填充用户看到的UITableView 所以我的问题是,您能创建一个在所有类中都引用的静态FMDatabaseQueue吗 我的第二个问题是,我的查询当前的格式是否为

我有一个应用程序,它使用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
将为您打开数据库。好的,我已经更改了所有代码,它工作正常,非常感谢您的帮助