2013-05-15 28 views
1

我對這個主題進行了長時間的研究,但是找不到解決方案。我很新的iPhone應用程序開發在Xcode所以請讓答案理解哈哈。我跟着蘋果的「你的第二個iOS應用程序」教程,並使主細節應用程序完美工作,但現在我想保存用戶輸入的數據,以便在重置應用程序後顯示它。代碼與蘋果教程上的內容相同here如何保存主細節應用程序的數據,以便在應用程序之後加載它?

在此先感謝!

回答

2

您需要做出兩項主要決定:您將如何存儲數據以及您何時要存儲/檢索數據。我們從如何存儲數據開始。

如何存儲數據

有你可以採取三種主要方法:保存到一個文件,保存到一個SQLite數據庫(有或沒有包裝,如FMDB),使用CoreData。最終你會想掌握SQLite和CoreData,但現在我建議採取第一種方法。

如果要保存到/從文件中讀取,則需要確定格式。有許多不同的選項,包括XML,JSON,自定義格式等。實際上,對於「真實」項目,根據項目目標,JSON等格式可能是一個不錯的選擇。但是,我將討論使用序列化存檔,因爲很多機器已經就位。

存儲數據的存檔,您將使用NSKeyedArchver將數據寫入到文件中。稍後,您將使用NSKeyedUnarchiver從文件中檢索信息。這些類編碼/數據解碼/從然後可以通過線路發送的字節流寫入到文件等

你的主要的數據結構是NSMutableArray的命名masterBirdSightingList,所以歸檔需要對數組進行編碼。 NSArray及其可變對象已經知道如何對自己進行編碼/解碼:它們只是對每個元素進行編碼/解碼以及一些簿記信息。所以這個謎題有一個缺失的部分。您需要指定如何編碼/解碼BirdSighting類的實例。

要指定此項,請修改該類以使其實現協議。在BirdSighting.h,在@interface聲明中更改到

@interface BirdSighting : NSObject <NSCoding> 

實施NSCoding是直線前進。我在上面提到,各種數組類都知道如何對自己進行編碼/解碼,即他們已經實現了NSCoding協議。那麼編碼/解碼BirdSighting,我們只需要對這個類的每個數據成員進行編碼/解碼。看看源代碼,我看到他們是兩個NSStrings和一個NSDate。但是這些類中的每一個都已經實現了NSCoding。因此,爲了對BirdSighting實例進行編碼/解碼,我們只需要告訴每個實例變量來編碼/解碼它們自己。我們做的方法的initWithCoder所有這些工作:encodeWithCoder:您添加到BirdSighting類。

注意:我正在粉飾的細節之一是存檔和鍵控歸檔之間的差別。通常情況下,您需要使用鍵控歸檔器,因此需要三個宏定義。說實話,我會創建NAME_KEY等,作爲靜態NSString常量而不是宏。

#define NAME_KEY @"name" 
#define LOCATION_KEY @"location" 
#define DATE_KEY @"date" 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super init]; 
    if (self) { 
     _name = [aDecoder decodeObjectForKey:NAME_KEY]; 
     _location = [aDecoder decodeObjectForKey:LOCATION_KEY]; 
     _date = [aDecoder decodeObjectForKey:DATE_KEY]; 
    } 
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)aCoder 
{ 
    [aCoder encodeObject:self.name forKey:NAME_KEY]; 
    [aCoder encodeObject:self.location forKey:LOCATION_KEY]; 
    [aCoder encodeObject:self.date forKey:DATE_KEY]; 
} 

還要說明一點,因爲BirdSighting直接從NSObject的繼承(其中沒有實現NSCoding),我用self = [super init]。如果父級確實使用實施NSCoding,則您需要執行self = [super initWithCoder:aCoder]

通過以上操作,保存到文件或讀取文件很容易。某處在BirdSightingDataController,大概在initializeDefaultDataList,我們插入如下:

masterBirdSightingList = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; 

其中路徑是包含于歸檔文件的目錄路徑的信息需要錯誤檢查和處理通常告誡一個NSString生產代碼(例如,如果該文件不存在)。

保存數據也很容易。我們可以添加一個方法,如下面的BirdSightingDataController對象:

- (BOOL)archiveToPath:(NSString *)path 
{ 
    BOOL success = [NSKeyedArchiver archiveRootObject:self.masterBirdSightingList]; 
    return success; 
} 

當存儲數據

現在,我們已經制定代碼保存和恢復數據,我們需要決定什麼時候我們要執行這些操作。在這裏,我將會更加模糊一些,因爲其他問題(例如整體應用程序結構)會發揮作用。然而,應用程序委託是管理,因爲有關的背景,例如applicationWillResignActive運行方法列表的封存和解除封存一個可能的候選人:applicationWillEnterForeground:

在進入後臺之前刪除目錄列表的內存副本是件好事。這表明將代碼創建到應用程序委託中。相反,您應該考慮延遲加載列表,即在您準備好顯示它之前不要檢索它,並且這意味着要將代碼檢索到BirdSightingDataController的init方法中的列表。

現在你的挑戰是做到這一切,而不是過度耦合和過度複雜化你的應用程序。但是我會把這個討論留給另外一個問答。答:

+0

首先,非常感謝你的深入迴應。其次,xcode接受除archiveToPath方法之外的所有代碼,它說「沒有已知的選擇器類archiveRootObject'」和「不兼容的整數轉換指針'BOOL'(又名'signed char'),其類型爲' ID';」 – Alex

+0

沒關係,我想通了。謝謝!!這有很大幫助。 – Alex

相關問題