if (sqlite3_open_v2("SoundLib", &dbConnection, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) {
// 報錯:out of memory(實為路徑無效導致無法分配頁面緩存)
}
直接傳遞字串 "SoundLib" 而非完整路徑的 UTF8String,SQLite 嘗試在當前工作目錄創建/打開文件,失敗後返回誤導性錯誤碼。
// 1. 獲取 Documents 目錄下的完整路徑
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths firstObject];
NSString *dbPath = [docDir stringByAppendingPathComponent:@"SoundLib_DB.sqlite"];
// 2. 檢查/複製種子數據庫(同原代碼)
// ...
// 3. 正確打開:路徑轉 UTF8String
sqlite3 *db = nil;
int rc = sqlite3_open([dbPath UTF8String], &db); // 或 sqlite3_open_v2
if (rc != SQLITE_OK) {
NSLog(@"SQLite open failed: %s", sqlite3_errmsg(db));
sqlite3_close(db);
return nil;
}
database = db;
UTF8String:SQLite C API 接受 const char*,NSString 需轉換編碼。SQLITE_NOMEM (out of memory) 而非 SQLITE_CANTOPEN,因為嘗試分配頁面緩存失敗。
// FMDB 示例
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
[queue inDatabase:^(FMDatabase *db) {
FMResultSet *rs = [db executeQuery:@"SELECT * FROM table"];
while ([rs next]) { ... }
}];
// 自動處理路徑、編碼、線程安全、事務
let dbPath = try FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("SoundLib_DB.sqlite")
.path
let dbQueue = try DatabaseQueue(path: dbPath)
try dbQueue.read { db in
let rows = try Row.fetchCursor(db, sql: "SELECT * FROM table")
while let row = try rows.next() { ... }
}
iOS SQLite out of memory 多為**路徑錯誤/未轉 UTF8String**導致的誤導性錯誤。正確做法:sqlite3_open([fullPath UTF8String], &db)。強烈建議使用 FMDB/GRDB 等封裝庫,避免底層 C API 陷阱。