首页 > 解决方案 > NSMutableDictionary 和 mutableCopy

问题描述

我对下面的代码感到困惑。在我添加 mutableCopy 行之前,它不起作用。在我添加该行之后,它确实如此。

为什么 aDict 一开始就不是可变的?我将 aDict 声明为 NSMutableDictionary。

- (void) myRoutine: (NSMutableDictionary *) dictOfDicts
   {
   NSMutableDictionary * aDict = dictOfDicts[dictOfDictsKey];
   int                   data  = [aDict[aDictKey] intValue];

   aDict           = [aDict mutableCopy];
   aDict[aDictKey] = @(++data);
   }

标签: objective-cnsmutabledictionarymutability

解决方案


The declaration of dictOfDicts says it's a pointer to a mutable dictionary. However, it does not use Objective-C generics syntax to say what the types of the keys or values are. So, the most we (and the compiler) can assume is that the keys are id<NSCopying> and the values are id, completely generic object pointers.

You then initialize your aDict variable with a value obtained from dictOfDicts. You've declared that aDict is also a pointer to a mutable dictionary. That's its "static type", but the real type of the object it points to is determined at runtime by whatever object is held in dictOfDicts under that key. It might be a mutable dictionary or it might be something else. It compiles just find because the compiler can't know what type of object that value is.

However, the real type (a.k.a. "dynamic type") of the object governs what operations succeed or fail/crash/whatever. In your case, it sounds like it's an immutable dictionary. So, when you attempt to mutate it, "it didn't work" (you don't specify what actually happened).

You make a mutable copy and you're allowed to mutate that. However, that's now a separate object that the one in dictOfDicts. So, you're not modifying what you think you are.

The solution is to put mutable dictionaries into dictOfDicts in the first place. Or, even better, put objects of a custom class of your own design into it, and operate on real properties.


推荐阅读