0

我有一个包含一个静态变量“数据库”的类,它代表一个用 sqlite 实现的数据库和一个函数 getAllShop,它的任务是调用存储在数据库中的所有数据并将它们填充到一个可变数组中

#define kFilename @"negozi.sqlite"

@implementation ShopDatabase

static ShopDatabase *database;

+(ShopDatabase *)database{
    if (database==nil) {
        database = [[ShopDatabase alloc] init];
        return database;
    }
}

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

    // Create the path to the database in the Documents directory for the bundle itself is not writable
    NSArray *pathsToDocuments = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [pathsToDocuments objectAtIndex:0];
    databasePath = [documentsDirectory stringByAppendingPathComponent:kFilename];
    if (![[NSFileManager defaultManager] isReadableFileAtPath:databasePath]) {
        if ([[NSFileManager defaultManager] copyItemAtPath:yourOriginalDatabasePath toPath:databasePath error:NULL] != YES)
            NSAssert2(0, @"Fail to copy database from %@ to %@", yourOriginalDatabasePath, databasePath);
    }

    // --- open db
    if(sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK){
        NSLog(@"Failed to open database");
    }else {
        NSLog(@"Database opened");
    }
}
return self;
}

- (NSMutableArray *) getAllShops{

// ------ read all the db
NSMutableArray *returnArray=[[NSMutableArray alloc] init];
NSString *query= @"SELECT * FROM negozio";
sqlite3_stmt *statement;

if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL) == SQLITE_OK){
    NSLog(@"Prepared database");
    while (sqlite3_step(statement)==SQLITE_ROW) {
            int uniqueId = sqlite3_column_int(statement, 0);    
            NSMutableString *nome = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)];
        ShopInfo *info= [[ShopInfo alloc] initWithUniqueId:uniqueId nome:nome];
        [returnArray addObject:info];
    }
    sqlite3_finalize(statement);
}

return returnArray;
}

@end

当我必须从另一个类的数据库中获取数据时,我会这样做,调用 getAllShop 并且一切顺利。通过这种方式,我将数据库的所有数据都放入了我的数组 shopinfo 中:

NSMutableArray *shopInfo=[[ShopDatabase database] getAllShops];

现在,我的数据库包含我需要用来填充两个表视图的数据,所以我需要执行两次:一次在代表第一个表视图的类中,一次在第二个。当我在第一个视图中执行此操作时一切顺利,但是当我第二次执行相同操作时,Xcode 给了我一个 exc bad access 错误。我尝试在同一个类中执行代码两次,这就是我得到的

2012-05-11 13:06:54.897 Shopping Mall[11333:707] -[NegozioPartenza getAllShops]: unrecognized selector sent to instance 0x14b8c0
2012-05-11 13:06:54.899 Shopping Mall[11333:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NegozioPartenza getAllShops]: unrecognized selector sent to instance 0x14b8c0'
*** First throw call stack:
(0x33ad188f 0x325c3259 0x33ad4a9b 0x33ad3915 0x33a2e650 0xa4141 0x35727e33 0x3574c629 0x35710d7d 0x357d34dd 0x3571955d 0x3571940b 0x357d34a3 0x35788873 0x357881b7 0x357d1d89 0x357d04eb 0x3582b82b 0x33a2b3fd 0x35709faf 0x35709f6b 0x35709f49 0x35709cb9 0x3570a5f1 0x35708ad3 0x357084c1 0x356ee83d 0x356ee0e3 0x32fa622b 0x33aa5523 0x33aa54c5 0x33aa4313 0x33a274a5 0x33a2736d 0x32fa5439 0x3571ce7d 0xa2515 0xa24c0)

终止称为抛出异常(lldb)

我是目标 C 的新手,所以我无法理解有什么意义。如何在静态变量上调用两次函数?谢谢你。

编辑:也许调用 [ShopDatabase 数据库] 激活第二次初始化的构造函数弄得一团糟?当我说一个变量是静态的时,这意味着该类的每个对象只有一个实例,对吗?那么我如何在第一次创建该唯一实例后访问它呢?我想我搞砸了当你使用静态变量时会发生什么......

4

2 回答 2

1

在你第一次打电话后的某个地方,database正在被释放。随后,NegozioPartenza在同一位置创建类型对象。第二次调用[ShopDatabase database]返回这个对象,然后你发送-getAllShops到那个对象,它显然没有实现那个方法。

于 2012-05-11T11:40:57.437 回答
1

您在第二次通话中没有有效的回报。

+(ShopDatabase *)database{
    if (database==nil) {
        database = [[ShopDatabase alloc] init];
        return database;
    }
}

在第二次调用数据库不是零,你不返回任何东西。您应该收到警告,并非所有控制路径都返回值。

这是正确的方法。

+(ShopDatabase *)database{
    if (database==nil) {
        database = [[ShopDatabase alloc] init];
    }

    return database;
}
于 2012-05-11T13:28:17.433 回答