为什么我不能从我的控制器添加到我的模型中的字典?

时间:2013-04-04 17:29:08

标签: ios objective-c model-view-controller initialization nsmutabledictionary

我的模型用于存储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属性的键,从而检索我需要的所有内容。
  4. 步骤2中的那些NSMutableDictionary属性没有响应。他们没有设置键或值;他们仍然是空的。从其他问题来看,这似乎是因为它们没有初始化。另外,从其他问题来看,我已经能够为我初始化的任意NSMutableDictionary添加和删除键/值(不是模型的一部分)。

    控制器应该对与模型相关的初始化视而不见,但我似乎无法通过覆盖模型的getters / 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
        }
    

2 个答案:

答案 0 :(得分:2)

我猜您的代码现在应该正常运行。我很好奇你是如何复制NSDictionaries并认为问题可能在那里。显然,您发现您尚未初始化tempDictBecauseAllocNeeded。除非你保持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时,它们仍然是可变的,当然。

答案 1 :(得分:0)

stuff = ( ...

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

stuff = [ ...