2009-12-12 62 views
3

我有下面的代碼應在更新NSUserDefaults的值:如何更新NSUserDefault

- (id) createBoardWithTitle:(NSString *)pTitle withScores:(NSArray *)pScores andNames:(NSArray *)pNames andDisplayStrings:(NSArray *)pStrings orderBy:(NSString *)pOrder ofType:(NSString *)pType 
{ 

    if((self == [super init])) 
    { 

     boardEntries = [NSMutableArray arrayWithCapacity:10]; 

     // Build the data 

      for(...){ 
       // populate boardEntries 
      } 


     // create an Dictionary to save 
     NSDictionary *savedData = [NSDictionary dictionaryWithObjectsAndKeys:pType, @"type", pOrder, @"order", boardEntries, @"entries", nil]; 

      // Load the old boards 
     NSDictionary *existingBoards = [[NSUserDefaults standardUserDefaults] objectForKey:@"BlockDepotLeaderboards"]; 

      // Create a mutable dictionary to replace the old immutable dictionary 
     NSMutableDictionary *newBoards = [NSMutableDictionary dictionaryWithCapacity:[existingBoards count]+1]; 

      // transfer the old dictionary into the new dictionary 
     [newBoards addEntriesFromDictionary:existingBoards]; 

      // add the new board to the new dictionary 
     [newBoards setObject:savedData forKey:pTitle]; 

      // check to make sure it looks like it should by eye 
     NSLog(@"New Boards: %@", newBoards); 

      // Replace the old date in NSUserdefaults 
     [[NSUserDefaults standardUserDefaults] setObject:newBoards forKey:@"BlockDepotleaderboards"]; 
      // Update: Do I really need to call this? 
     [[NSUserDefaults standardUserDefaults] synchronize]; 

      // Check to make sure it looks as it should by eye 
     NSLog(@" Defaults--- %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"BlockDepotLeaderboards"]); 
    } 

    return self; 

} 

至於我可以告訴大家,這是相關代碼。或許它可能比它更「單調」。但據我所知,從NSUserDefaults返回的任何東西都是不可變的,所以我必須重新創建它作爲一個可變的對象,添加需要添加的東西,然後替換NSUserDefaults中的對象。而且我認爲我上面的嘗試應該是有效的。

的輸出的NSLog(@ 「的新版塊:%@」,newBoards)ID

New Boards: { 
    "Marathon: Times" =  { 
     entries =   (
         { 
       displayString = "10:00"; 
       name = "Tom Elders"; 
       score = 600; 
      }, 
         { 
       displayString = "10:30"; 
       name = "A.R. Elders"; 
       score = 630; 
      }, 
         { 
       displayString = "11:00"; 
       name = "L. Lancaster-Harm"; 
       score = 660; 
      }, 

      // and so on..... 

     ); 
     order = ASC; 
     type = TIMES; 
    }; 
    String = Test; 
} 

「字符串=測試」 只是一個測試項,這樣在AppDelegate.m文件中設置:

if(![[NSUserDefaults standardUserDefaults] objectForKey:@"BlockDepotLeaderboards"]){ 

    NSMutableDictionary *leadboardHolder = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Test", @"String", nil];  
    [[NSUserDefaults standardUserDefaults] setObject:leadboardHolder forKey:@"BlockDepotLeaderboards"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 



}else{ 
    NSLog(@"Leaderboards Dict Exists %@", [NSUserDefaults standardUserDefaults]); 
} 

所以我知道我在之後肯定是有。我只是知道這將是我錯過的一些愚蠢的東西。但是我看不到它或者搞清楚了。

任何人都可以看到我搞砸了嗎?

+0

不要做'objectForKey:@「BlockDepotLeaderboards」'。你不知道返回的對象實際上是什麼。使用-dictionaryForKey:來代替,並通過創建一個新字典來處理它爲零的情況。 – 2009-12-12 17:13:00

+0

如果您正在訪問NSUserDefaults的值,您應該使用dictionForKey:或將該對象的類型轉換爲字典 – 2009-12-13 07:39:17

回答

5

至於我可以告訴大家,這是相關代碼。或許它可能比它更「單調」。但據我所知,從NSUserDefaults返回的任何東西都是不可變的,所以我必須重新創建它作爲一個可變的對象,添加需要添加的東西,然後替換NSUserDefaults中的對象。

更簡單的方法是使不可變的字典這樣的mutableCopy:

NSMutableDictionary *newBoards = [[immutableDict mutableCopy] autorelease]; 
[newBoards setObject:savedData forKey:pTitle]; 

此外,synchronize用於強制保存用戶默認的磁盤。這隻會影響你在Finder中打開plist時看到的內容。從應用程序的角度來看,NSUserDefaults始終是最新的。此外,默認值會每隔一段時間自動保存,所以您可能需要致電synchronize的唯一時間是應用程序終止時。

0

根據該文檔:

默認對象必須是一個屬性 列表,也就是,的一個實例(或用於 集合實例 的組合):NSData的,的NSString,的NSNumber, NSDate,NSArray或NSDictionary。

你確定所有你試圖連載的對象嗎?看看NSKeyedArchiver

也期待在這個問題Why NSUserDefaults failed to save NSMutableDictionary in iPhone SDK?

+0

我正在其他地方使用NSKeyedArchiver。這個項目主要是一個自我教學項目,所以我想弄明白。但我在想同樣的事情;據我所知,我試圖保存一個NSDictionary,有兩個NSString和一個NSarray,它包含10個包含兩個NSString和NSNUmber的NSDictionaries。但我會回去瑣碎檢查它。 – gargantuan 2009-12-12 14:19:21

0

起初保存任何東西:

[[NSUserDefaults standardUserDefaults] setObject:@"Previous Value" forKey:@"Name"]; 

然後再次運行該代碼相同的密鑰的更新值:

[[NSUserDefaults standardUserDefaults] setObject:@"Updated Value" forKey:@"Name"]; 

你不需要調用[[NSUserDefaults的standardUserDefaults] 同步]由於性能問題。只有它是必需的。 iOS 管理得很好。

你不需要刪除對象。只需更新相同的密鑰。它將更新該特定密鑰的值。 希望這有助於。