2009-04-27 48 views
1

我正在開發iphone-sdk 2.2.1(所以沒有CoreData cry)。DB包裝器無法響應消息?

所以我使用的是FMDatabase project,它只是Obj C中的一個SQLite包裝器。我的數據庫在與我的AppDelegate進行交互時運行良好。我已經從AppDelegate測試了連接,插入等。

現在,我有一個數據對象,我想存儲到數據庫中。我想從ViewController類中發生這個事件。讓我們看一些代碼:

應用程序委託在applicationDidFinishLaunching方法中創建數據庫。 DB被聲明爲這個類的一個屬性,所以我可以輕鬆訪問它。

db = [FMDatabase databaseWithPath:[self getDBPath]]; 

這工作正常,我測試了它。我有點關心的唯一事情就是'db'是這個類的一個屬性。那應該不會造成問題,應該如何?

從相同的applicationDidFinishLaunching方法,我測試了一個簡單的插入使用。這個工程:

[db beginTransaction]; 
[db executeUpdate:@"INSERT INTO tblDataSamples (...) VALUES (...);"]; 
[db commit]; 

現在,如果我只是藉此確切的代碼,並將其移動到AppDelegate中的一個實例方法,代碼不再工作。當我們點擊[db beginTransaction]行時,出現"EXC_BAD_ACCESS"錯誤。

此代碼對此調用的流程: - AltViewController接收按鈕事件 - AltViewController告訴ApplicationDelegate執行「addSample」方法。 - ApplicationDelegate的addSample方法在[db beginTransaction]上失敗。

現在我已經寫了這個,我認爲問題是我的數據庫在ApplicationDelegate加載RootView後丟失。也許我錯了。有人有主意嗎?

!!!!!!!!!

更新! 我只是改變了我的addSample方法包括:

db = [FMDatabase databaseWithPath:[self getDBPath]]; 
    if (![db open]) { 
     NSLog(@"Could not open db."); 
    } 

[db close]; 

現在的整個事務工作。所以,新的問題是:我如何讓數據庫打開ONCE並保持在不同的視圖和viewControllers中打開?

+0

使用Sqlite3 API可能會更容易。它非常簡單和簡潔。您可以輕鬆地爲您實際使用的功能創建對象包裝器/便利。 – 2009-04-28 00:27:42

+0

使用db = [[FMDatabase databaseWithPath ...] retain]或[self setDb:[FMDatabase databaseWithPath ...]],其中db設置爲具有「retain」屬性的屬性 – lostInTransit 2009-04-28 04:38:57

回答

2

您遇到問題了,因爲您還不知道內存管理規則。在這種情況下,databaseWithPath:方法將返回一個自動釋放對象,該對象在運行循環結束時處理。儘管你的數據庫指針仍然指向無效的內存位置,這就是爲什麼當你嘗試稍後訪問它時看到EXC_BAD_ACCESS錯誤。

好消息是內存管理其實很容易在Cocoa學習。首先看看this page,它應該有足夠的信息讓你走。爲了解決這個特殊的問題,你需要在db對象創建後調用retain方法,並在不再需要的時候釋放它(如果你在應用程序的整個生命週期中保留它,沒有什麼能夠釋放它,但是這仍然是一個好習慣)。