2011-07-28 28 views
4
的NSKeyedArchiver我

認爲這是一個初學者的有關數據管理的問題。與NSUserDefaults的

我有一個應用程序,它加載和保存不同的txt文件。我想給每個txt文件保存在txt文件中的某些特性,例如名稱,樣式,顏色等。

我到目前爲止所做的事情是創建一個NSMutableArray * myLibrary,我將其中所有這些引用。該陣列是這樣的:

  • 每個txt文件一個對象被添加到在MyLibrary
  • 每個對象擁有幾個NSString的,NSUInteger,布爾值將和一些NSMutableArrays
  • 在我的子類

    這些對象,我與

    工作 - (ID)的initWithCoder:(NSCoder *)aDecoder; - (void)encodeWithCoder:(NSCoder *)aCoder;

現在,我的大問題是什麼是最好的和最安全的方式是要持之以恆此數據。到目前爲止,我已經與的NSKeyedArchiver工作,但用戶報告數據丟失和出現了,其中iTunes同步據稱造成數據被搞砸了一個奇怪的情況。 NSUserDefaults是否有任何保護程序?每當用戶做出更改時,我都會保存myLibrary.dat,因此我不明白爲什麼它不應該是100%保存。任何意見/建議/解釋將非常感謝!

這裏是我寫和讀碼myLibrary.Dat:

-(NSString*)documentsDirectory 
{ 
    NSLog(@"documentsDirectory"); 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory 
    return documentsDirectory; 
} 

-(void)saveLibraryDat { 

    NSLog(@"Saving myLibrary.dat..."); 
    NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:@"myLibrary.dat"]; 
    BOOL succeed = [[NSKeyedArchiver archivedDataWithRootObject:myLibrary] writeToFile:filePath atomically:YES]; 
    if (!succeed){ // do something } 

} 


-(void)loadLibraryDat { 

    NSLog(@"loadLibraryDat"); 
    NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:@"myLibrary.dat"]; 

    self.myLibrary = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 

    if (self.myLibrary == nil) { 
     NSLog(@"myLibrary.dat empty... set up new one"); 
     [self setupLibrary]; 
    } else { NSLog(@"Loading myLibrary.dat successful."); } 

} 

編輯:我的編碼方法是這樣的:

- (id)initWithCoder:(NSCoder *)aDecoder { 
    self = [super init]; 
    if (self) { 
     self.titleName = [aDecoder decodeObjectForKey:@"titleName"]; 
     self.fileName = [aDecoder decodeObjectForKey:@"fileName"]; 
     self.fileFont = [aDecoder decodeObjectForKey:@"fileFont"]; 
self.tabTitles = [aDecoder decodeObjectForKey:@"tabTitles"]; 
    } 
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)aCoder { 
    [aCoder encodeObject:titleName forKey:@"titleName"]; 
    [aCoder encodeObject:fileName forKey:@"fileName"]; 
    [aCoder encodeObject:fileFont forKey:@"fileFont"]; 
    [aCoder encodeObject:tabTitles forKey:@"tabTitles"]; 
} 

@end 

在標題中這些被定義如:

NSString *titleName; 
NSString *fileName; 
NSString *fileFont; 
NSMutableArray *tabTitles; 
+1

那四個成員變量是什麼類型的?的NSString *? –

+0

@Matthieu Cormier:對不起,他們是NSStrings和NSMutableArrays。我也有BOOL,NSUInteger,但不希望把它們包含在這裏,以使它不那麼複雜。 –

回答

3

不要用戶NSUserDe故障。這是更多的默認設置,如我應該啓動時顯示窗口X. NSUserDefaults不是爲程序數據設計的。你應該像你在做的那樣使用NSKeyArchiver。該錯誤很可能在myLibrary包含的對象中。

你應該看一看(或郵寄)的功能:

- (id)initWithCoder:(NSCoder *)coder 
- (void)encodeWithCoder:(NSCoder *)coder 

這是最有可能在那裏您的問題所在。

+0

非常感謝。但我沒有看到問題可能出現在我的編碼器方法中(我將它們包含在我的更新後的文章中)。它適用於我100%和任何時候,所以我根本不明白爲什麼有些用戶有問題,他們的數據被刪除等 –

+0

我已經更新我的問題與我使用的變量類型。謝謝你的幫助 - 非常感謝。聽到人們正在丟失數據令人沮喪... –

+0

你能重現他們的問題嗎?你有這個bug的任何再現步驟? –

1

用戶可以訪問的iOS5下和任何版本的文件目錄,如果他們使用越獄的手機。改爲將您的文件保存到~/Library/Application Support/appname

NSMutableString *path = [[NSMutableString alloc] init]; 
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSApplicationSupportDirectory, NSUserDomainMask, YES); 
[path appendString: [paths objectAtIndex: 0]]; 
[path appendString: @"/YOURAPPNAME"]; 

編輯

你貼優秀作品,如果你的數組包含NSCoding支持的數據類型不應該有任何問題的代碼。作爲一個風格問題,我會使用一個常量作爲關鍵字來避免在鍵中輸入錯誤。例如:您的@implementation部分上方的NSString *const kTitleName = @"kTitleName";

+0

是的,如果有人可以發表評論,那會很有幫助。我想人們不喜歡將數據保存在應用程序支持文件夾中?不知道! –

+1

感嘆,這個-2的任何理由?使用NSKeyedArchiver和支持可變數組的對象(不像以前發佈的,現在已被刪除)或者bools作爲NSNumber是沒有問題的。所以除非你的非發佈代碼是錯誤的(你應該單元測試它),我必須猜測有人已經搞亂了你的conf文件。 – Jano

+0

謝謝Jano。仍在等待人們解釋爲什麼他們投了票。當你說「數組包含NSCoding支持的數據類型」時,你的意思是我應該只把例如NSStrings或整數到NSMutableArray tabTitles,對吧?不知道錯誤來自哪裏......以及因爲我的應用程序而丟失數據的人是非常令人不安的想法。 –

0

正如其他人所說,考慮到您正在存儲應用程序數據而不是簡單的默認設置,NSKeyedArchiver是比NSUserDefaults更好的解決方案。

關於你的數據丟失的問題......如果時間之間的應用程序崩潰,他們進入的數據,並且成功地調用saveLibraryDat

用戶可能會丟失數據。您可以嘗試Crashlytics之類的軟件來監控最終用戶的應用程序崩潰。

如果succeedsaveLibraryDat爲假,用戶也可能會丟失數據。將// do something替換爲有意義的錯誤處理。也許設備上沒有剩餘空間來保存數據。