【问题标题】:Objective-C method returns NSDictionary instead of NSMutableDictionary. Why?Objective-C 方法返回 NSDictionary 而不是 NSMutableDictionary。为什么?
【发布时间】:2012-08-10 02:27:58
【问题描述】:

我正在使用包含的方法返回指向 NSMutableDictionary 的指针,该指针包含在 NSArray 中。然而,NSMutableArray (theOne) 被创建为一个不可变的 NSDictionary。这是一个问题,因为我想在使用此方法检索字典后对其进行修改。

- (NSMutableDictionary*)getMatFromBoutKey:(NSString*) boutKey
{   
    /*
     * Returns the mat object with the provided boutKey.
     * Returns nil if no mat has that boutKey.
     */

    NSUInteger idx = [[event objectForKey:@"mats"] indexOfObjectPassingTest:
                      ^ BOOL (NSMutableDictionary* obj, NSUInteger idx, BOOL *stop)
                      {
                          return [[obj objectForKey:@"boutKey"] isEqualToString:boutKey];
                      }];

    if (idx == NSNotFound)
        return nil;
    else {
        NSMutableDictionary* theOne = [[event objectForKey:@"mats"] objectAtIndex: idx];
        return theOne;
    }
}

这是调试器在第一次引用 theOne 后在断点处停止的图像。

为什么 theOne 不是可变的?如何返回指向 NSMutableDictionary 的指针,以便在获得返回给我的值后对其进行修改?

谢谢!

【问题讨论】:

  • [event objectForKey:@"mats"] 是可变字典数组吗?
  • 什么是事件?这是从哪里来的?
  • 不要在方法前面加上get。那应该只是matFromBoutKey:
  • 是的,[event objectForKey:@"mats"] 是一个可变字典数组。我在另一个班级创建事件。 Event 是该类和保存上述代码的类的属性。谢谢@bbum,我会做出改变的。

标签: objective-c nsmutablearray objective-c-blocks


【解决方案1】:

我将假设您有一个数组字典。然后该数组包含一堆常规字典。因此,当您将其从数组中拉出时,无论您将其分配给什么,它仍然是一个常规字典。

例如,以下面的代码为例

NSDictionary *dict = [[NSDictionary alloc] init];
NSMutableDictionary *mutDict = dict;

mutDict 将包含一个常规字典,因为它没有正确地转换为可变字典。

要么确保在创建位于 [event objectForKey:@"mats"] 的数组时将 NSMutable 字典放入其中,要么

使用

NSMutableDictionary* theOne = [[[event objectForKey:@"mats"] objectAtIndex: idx] mutableCopy];

取出数据时

【讨论】:

  • 是的,事件是一个 NSMutableDictionary,带有一个称为 mats 的 NSArray,mats 包含 NSMutableDictionaries。我确实将 NSMutableDictionaries 放入数组中。如果我在取出字典时使用 mutableCopy,那只会给我一个副本,而不是指向真实对象的指针,对吗?我正在深入研究我是如何放入字典的,以确保它们按照我的想法进行。
  • 我发现了问题。有一个循环将垫子重新分配给 NSDictionaries。它是固定的。现在。谢谢!
【解决方案2】:

一般来说,我认为当可变性不是绝对必要时使用不可变对象是更好的做法。可变对象使用更多内存,当然也有可能被意外更改。也许在块中被更改为枚举器(我不确定,但有可能。为了更快的索引)。如果你想改变一个可变对象是通过mutableCopy。或使用其他方法。

【讨论】:

  • 我实际上认为可变对象需要更多内存是一个常见的误解。据我了解,NSMutableDictionary 只是 NSDictionary 的一个子类,上面有更多方便的方法。 NSDictionary 上的一个类别可能也可以做到这一点。
  • 可变对象需要更多内存,速度较慢,而且——真正的原因——打破封装,导致脆弱。请注意,对于只有少数对象的集合,性能差异可以忽略不计。然而,脆弱性是一个重大问题。
  • 我理解脆弱性问题,但是,您能否将来源发布到您获取信息的来源,即它们速度较慢且需要更多内存?我几乎可以肯定我看过一个 WWDC 视频,其中一位 Apple 工程师说它们只是一个带有便利方法的简单子类。
  • 就我而言,我使用的是可变字典,因为我需要定期访问它们的内容。我只从一个地方改变它们。我不确定我能做些什么来保护他们。
  • 你不应该使用可变字典。如果您在字典中不断添加、删除和更改对象,则使用 MutableDictionaries。您可以根据需要访问常规 NSDictionary 的内容。一旦创建了字典,您就无法添加、删除和更改键值对。
【解决方案3】:

它是否以可变的形式插入到代码的其他地方?如果是这样,它应该以可变的形式返回,如果不是,您可以向它发送 mutableCopy 消息以获取可变副本(引用计数为 1,因此请务必在必要时释放它)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多