objective-c - 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);
}
解决方案
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.
推荐阅读
- ehcache - Ehcache 缓存数据,支持集群磁盘存储(复制)
- python - 动画插值 Python Matplotlib
- laravel - How to put the condition on User table with condition on subject table
- python - SVN 以编程方式更新 - python
- mysql - MySQL 连接表并显示不包括特定 user_id 的值
- postgresql - PostgreSQL:更改选择查询返回的所有表
- bash - 如何在 shell 中使用 $var$i
- r - 在绘图中重新定位颜色条并更改颜色比例(R)
- curl - curl TLS握手不成功
- sql - oracle中是否有与concat_ws等价的东西?