存储一个数组,每次只保存一个成员?

Store an array where I only save one member each time?

我想存储一个数组,以便它在启动时可用。数组中的每一项代表列表中的一项,在保存到数组之前转换为JSON格式。

我一直将它保存到 NSUserDefaults,但我不想每次要更改其中的单个项目时都必须将整个数组保存到 NSUserDefaults。理想情况下,我只是更改数组内部的值,而无需更改其他值。而且我还需要在数组中添加和删除项目,同样,我不想为了执行此操作而保存整个数组。

有没有更有效的方法?

现在,我一直在解决这个问题,每个项目都在自己的标识符下保存到 NSUserDefaults,并且每个标识符都有一个正确顺序的数组。这正在成为一个复杂的解决方案,但存在问题。

保存整个数组有什么问题?如果要编辑一项,从 NSUserDefaults 中获取数组(创建可变副本),更改相应的项,然后将数组保存回来。

为什么不使用 NSArray 而不是使用 NSDictionary 来保存数据,因为这将使您更容易在需要时获取数据并更容易转换为 JSON

所以我会做类似的事情:

// Few constants for keys
NSString const *itemsListKey = @"FruitItems";
NSString const *applesKey = @"Apples";
NSString const *bananasKey = @"Bananas";

创建新词典并将其添加到我们的 NSUserDefaults

NSMutableDictionary *items = [[NSMutableDictionary alloc] init];
[items setObject:5 forKey:applesKey];
[items setObject:2 forKey:bananasKey];

[[NSUserDefaults standardUserDefaults] setObject:items forKey:itemsListKey];
[[NSUserDefaults standardUserDefaults] synchronize];

检索现有词典并修改 NSUserDefaults

中的当前词典
// The dictionary retrieved isn't mutable so we need to get a mutable copy of it.
NSMutableDictionary *itemsRetrieved = [[[NSUserDefaults standardDefaults] dictionaryForKey:itemsListKey] mutableCopy];
// Lets update our Apples value
[itemsRetrieved setObject:9 forKey:applesKey];

// Set the dictionary back into NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:items forKey:itemsListKey];
[[NSUserDefaults standardUserDefaults] synchronize];

您会注意到这两种不同的方法之间并没有太大的区别,因此您可以将其集成到一种方法中,如下所示。

// Obviously this constant being the key to your dictionary
NSString const *itemsListKey = @"itemsList"; 

- (void)updateItemsForKey:(NSString *)key withValue:(NSInteger)value
{
    NSMutableDictionary *items [[NSMutableDictionary alloc] init];
    if ([[NSUserDefaults standardDefaults] dictionaryForKey:itemsListKey] != nil) {
        // If the key already exist in NSUserDefaults reallocate it 
        // to the one that exists.
        items = [[[NSUserDefaults standardDefaults] dictionaryForKey:itemsListKey] mutableCopy];
    }

    [itemsRetrieved setObject:value forKey:key]; 

    // Assign the dictionary back into NSUserDefaults
    [[NSUserDefaults standardUserDefaults] setObject:items forKey:itemsListKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
} 

编辑 - 基于他们希望订购的评论。

我们真的不关心 NSDictionary 是否按排序顺序排列。如果我们希望对象按排序顺序排列,我们可以在执行 allKeys 调用时将字典的键按排序顺序排列。

NSArray *orderedKeys =  [[items allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
}];

上面的代码会给你一个按数字排序的数组,然后你遍历 orderedKeys 数组以按照你想要的顺序获取你想要的值,比如:

for (NSString *key in orderedKeys) {
    id objectFromDict = [items objectForKey:key];
    // Do whatever you want with that object.
}