NSMutableDictionary 和 mutableCopy

NSMutableDictionary and mutableCopy

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

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

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

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

dictOfDicts 的声明说它是一个指向可变字典的指针。但是,它不使用 Objective-C 泛型语法来说明键或值的类型。因此,我们(和编译器)最多可以假设键是 id<NSCopying>,值是 id,完全通用的对象指针。

然后您使用从 dictOfDicts 获得的值初始化您的 aDict 变量。您已声明 aDict 也是指向可变字典的指针。那是它的 "static type",但它指向的对象的真实类型在运行时由该键下 dictOfDicts 中保存的任何对象确定。它可能是一个可变字典,也可能是其他东西。它编译只是找到,因为编译器无法知道该值是什么类型的对象。

但是,对象的实际类型 (a.k.a。"dynamic type") 决定哪些操作成功或 fail/crash/whatever。就您而言,这听起来像是一本不可变的字典。所以,当你试图改变它时,"it didn't work"(你没有指定实际发生了什么)。

你制作了一个可变副本,你可以改变它。但是,它现在是 dictOfDicts 中的一个单独的对象。所以,你并没有改变你认为的自己。

解决方案是首先将可变字典放入 dictOfDicts。或者,更好的是,将您自己设计的自定义对象 class 放入其中,然后对真实属性进行操作。