0

我的模型旨在存储 JSON 数据。要存储的部分内容是嵌套在 JSON 中的数组,它可以是不同数量的元素。这就是我在代码中检索该数据的方式。

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"SomeJsonFile" ofType:@"json"];
NSData *jsonFromFile = [[NSData alloc] initWithContentsOfFile:filePath];

NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:jsonFromFile options:0 error:&error];
DLog(@"simulated 'Stuff' JSON, stored in dictionary: %@", jsonData);

这很好用。一个回调沿着该字典发送,此时我遇到了我的问题。这是 JSON 中嵌套数组的示例。

        stuff =             (
                            {
                id = 11;
                "someState" = 1;
                someNumber = 100;
                description = "Human-readable text for thing #11!";
            },
                            {
                id = 22;
                "someState" = 0;
                someNumber = 20;
                description = "Human-readable text for thing #22!";
            },
                            {
                id = 33;
                "someState" = 1;
                someNumber = 250;
                description = "Human-readable text for thing #33!";
            },
        );

我的模型应该存储在那里发送的数据,但由于该嵌套数组是未知数量的元素,我选择:

  1. 使用 NSMutableArray 存储每个数组元素的 ID。
  2. 为元素的每个属性使用 NSMutableDictionary(如 someState、someNumber、description)。
  3. 当需要列出模型的所有元素时,我将遍历 ID 数组并将每个 ID 用作每个 NSMutableDictionary 属性的键,从而检索我需要的所有内容。

步骤 2 中的那些 NSMutableDictionary 属性没有响应。他们不设置键或值;它们保持为空。从其他问题来看,这似乎是因为它们没有被初始化。同样从其他问题来看,我已经能够向我初始化的任意 NSMutableDictionary(不是模型的一部分)添加和删除键/值。

控制器应该对与模型相关的初始化视而不见,但我似乎无法通过覆盖模型的 getter/setter 来初始化 NSMutableDictionary 属性。 在 Objective-C 中使用 NSMutableDictionary 属性设置我的模型以便我可以从控制器中设置键和值的正确方法是什么?

我也觉得我在数组解决方案中由 ids 索引的多字典是矫枉过正的。如果您能发现这一点并知道在 iOS 中处理此问题的更好方法,请随时提供您的智慧。

编辑 应 Marcus Adams 的要求,这是我使用 NSMutableDictionary 属性的代码。我没有初始化 NSMutableDictionary 属性;我的问题是在哪里这样做以使其适合 MVC 模型。他的回答使我尝试通过覆盖“init”来进行初始化,这作为模型实例化的一部分起作用(如果他提供解释,Marcus Adams 将被标记为答案,因为他引导我找到了答案,但是答案正确覆盖“init”的代码示例将被投票)。

 // Now we're ready to store what's in the JSON.
    NSDictionary *stuff = jsonData[@"stuff"];
    NSMutableDictionary *tempDictBecauseAllocNeeded = [[NSMutableDictionary alloc] init];
    for (NSDictionary *thing in stuff) {
        [tempDictBecauseAllocNeeded setObject:thing[@"description"] forKey:thing[@"id"]]; // This works!

        theModel.thingDescriptions[thing[@"id"]] = thing[@"description"]; // This wasn't working!
        [theModel.thingIds addObject:thing[@"id"]]; // This is the array of ids used to retrieve values from each dictionary
    }
4

2 回答 2

2

我想你的代码现在应该可以工作了。我很好奇您是如何复制 NSDictionaries 的,并认为问题可能就在那里。显然,你发现你没有初始化 tempDict,因为AllocNeeded。除非您将 tempDictBecauseAllocNeeded 保留一段时间,否则我不会使用 getter 进行初始化。如果是,将其存储为属性并在 getter 中对其进行初始化是最简单的事情。

// Getter ensures that when you reference self.tempDictBecauseAllocNeeded
/// it's always initialized
-(NSMutableDictionary *) tempDictBecauseAllocNeeded {
  if (!_tempDictBecauseAllocNeeded) {
    _tempDictBecauseAllocNeeded = [[NSMutableDictionary alloc] init];
  }
  return _tempDictBecauseAllocNeeded;
}

由于原始 JSON 解析默认创建可变叶子,即使您将其分配给 NSDictionary,其中的每个叶子仍然是可变的。

因此,当您(浅拷贝)将叶子复制到您的 NSMutableDictionary 时,它们当然仍然是可变的。

于 2013-04-04T18:35:29.393 回答
0
stuff = ( ...

这不是 JSON 数组,它应该是吗?JSON数组将是

stuff = [ ...
于 2013-04-04T17:55:28.520 回答