Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 创建singleton DB helper类_Ios_Sqlite_Helper - Fatal编程技术网

Ios 创建singleton DB helper类

Ios 创建singleton DB helper类,ios,sqlite,helper,Ios,Sqlite,Helper,我正试图编写一个主细节应用程序,从sqlite数据库获取数据。作为这项工作的一部分,我正在尝试创建一个帮助器类,该类将创建数据库的一个单例实例。我想让它做的就是初始化数据库,这样我就可以从应用程序的不同视图中引用它。 我在这里遵循了一个教程: 我得到的教程工作,但现在我试图修改它,以适应我的应用程序,我似乎无法让它工作。我没有错误或警告,但当我在模拟器上运行应用程序时,我输入的调试文本都不会执行。所以在我看来,我的init函数没有执行。我就是不明白为什么。 有人能在下面的代码中发现我的问题吗 忠

我正试图编写一个主细节应用程序,从sqlite数据库获取数据。作为这项工作的一部分,我正在尝试创建一个帮助器类,该类将创建数据库的一个单例实例。我想让它做的就是初始化数据库,这样我就可以从应用程序的不同视图中引用它。 我在这里遵循了一个教程:

我得到的教程工作,但现在我试图修改它,以适应我的应用程序,我似乎无法让它工作。我没有错误或警告,但当我在模拟器上运行应用程序时,我输入的调试文本都不会执行。所以在我看来,我的init函数没有执行。我就是不明白为什么。 有人能在下面的代码中发现我的问题吗

忠诚程序数据库

#import <Foundation/Foundation.h>
#import <sqlite3.h>

@interface LoyaltyProgramDatabase : NSObject {
    sqlite3 *_loyaltyProgDB;
}

@property (strong, nonatomic) NSString *databasePath; //Path file of our database
@property (nonatomic) sqlite3 *loyaltyProgDB; //Reference to the database

+ (LoyaltyProgramDatabase*)loyaltyProgDB;

@end
试试这个:

   + (id)allocWithZone:(NSZone *)zone
{
    return [self loyaltyProgDB];
}

+ (LoyaltyProgramDatabase*)loyaltyProgDB
{
    static BNRImageStore *loyaltyProgDB = nil;
    if (!loyaltyProgDB) {
        // Create the singleton
        loyaltyProgDB = [[super allocWithZone:NULL] init];
    }
    return loyaltyProgDB;
}

- (id)init {
    self = [super init];
    if (self) {

        NSString *docsDir;
        NSArray *dirPaths;

        // Get the documents directory
        dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

        docsDir = dirPaths[0];

        // Build the path to the database file
        _databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:@"loyaltyProg.db"]];

        NSFileManager *filemgr = [NSFileManager defaultManager];

        if ([filemgr fileExistsAtPath: _databasePath ] == NO)
        {
            const char *dbpath = [_databasePath UTF8String];

            if (sqlite3_open(dbpath, &_loyaltyProgDB) == SQLITE_OK)
            {
                char *errMsg;
                const char *sql_stmt = "CREATE TABLE IF NOT EXISTS scoreCard (ID INTEGER PRIMARY KEY AUTOINCREMENT, campaignID INTEGER, merchantName TEXT)";

                if (sqlite3_exec(_loyaltyProgDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
                {
                    //_status.text = @"Failed to create table";
                    NSLog(@"Failed to create table");
                }
                sqlite3_close(_loyaltyProgDB);
            } else {
                //_status.text = @"Failed to open/create database";
                NSLog(@"Failed to open/create database");
            }
        }
    }
    return self;
}

如果您没有编写一行代码说明
[[LoyaltyProgramDatabase alloc]init]
[LoyaltyProgramDatabase loyaltyProgDB]
,那么您的
init
函数永远不会被调用

启动应用程序时不会自动调用
init
。任何
init
函数只有在nib/xib/storyboard文件中有一个UI元素,并且应用程序使用各种初始化函数创建元素时才会自动调用,但决不会使用您自己的
init
函数。但是对于您编写的东西,要初始化数据库对象,您需要自己调用
init
函数

在您的应用程序委托中,在
didfishLaunching
功能下,输入以下行:

[LoyaltyProgramDatabase loyaltyProgDB];
顺便说一句,这不是一个真正最新的单身模式。这实际上是一个惰性加载程序函数。如果您想要更安全的单例,请使用以下代码

+(id)sharedInstance {
  static dispatch_once_t pred = 0;
  __strong static id _sharedObject = nil;
  dispatch_once(&pred, ^{
    _sharedObject = [[self alloc] init];
  });
  return _sharedObject;
}
这将确保数据库只初始化一次,并且是线程安全的。要创建/使用单例,代码将从上面更改为

[LoyaltyProgramDatabase sharedInstance]

你有没有打过电话给
[LoyaltyProgramDatabase loyaltyprogramdb]
?另外,那本教程是大约3年前的。。。非常过时。RayWenderlich应该有更好的教程。@ColdLogic不,我从来没有调用过
[LoyaltyProgramDatabase loyaltyProgDB]
,因为我的理解是没有必要,因为数据库是在
-(id)中启动的当应用程序启动时,init
自动运行。哦,我多么希望
init
函数被自动调用。但不幸的是,情况并非如此。由于没有显示任何NSLog,因此可以判断没有调用init。检查我在下面发布的答案。这不会给我任何错误或警告,但我的NSLog仍然没有显示。你必须调用loyaltyProgDB来创建和初始化singleton实例。即:LoyaltyProgramDatabase*LoyaltyprogdsingletoneInstance=[LoyaltyProgramDatabase loyaltyProgDB];
[LoyaltyProgramDatabase sharedInstance]