このクラスには、sqlite で実現されたデータベースを表す静的変数「データベース」と、db に格納されているすべてのデータを呼び出して可変配列に入力する関数 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];
現在、データベースには 2 つのテーブル ビューを埋めるために使用する必要があるデータが含まれているため、これを 2 回実行する必要があります。1 回目は最初のテーブル ビューを表すクラスで、もう 1 回は 2 番目のテーブル ビューを表します。最初のビューでこれを行うとすべてうまくいきますが、2 回目に同じことを行うと、Xcode で exc bad access エラーが発生します。同じクラスでコードを2回実行しようとしましたが、これが得られます
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)
私はObjective Cの初心者なので、何がポイントなのか理解できません。静的変数で関数を 2 回呼び出すにはどうすればよいですか? ありがとうございました。
編集: [ShopDatabase データベース] を呼び出すと、initializazione のコンストラクターがもう一度アクティブになり、混乱が生じる可能性がありますか? 変数が静的であると言うとき、それはそのクラスのすべてのオブジェクトに対してそのインスタンスが 1 つしかないことを意味しますよね? では、最初に作成した後にその一意のインスタンスにアクセスするにはどうすればよいですか? 静的変数を使用すると何が起こるかを台無しにしていると思います...