有没有办法在可可中将可变对象转换为不可变对象? 我使用过NSMutableDictionary * mut = [[NSMutableDictionary alloc] initWithDictionary:copyItems:]; 但是这个字典在许多其他地方使用而没有可变的东西。
最诚挚的问候, Subrat
答案 0 :(得分:7)
NSDictionary dictionaryWithDictionary:
答案 1 :(得分:3)
这可能是一个过于简单的答案,但是:
NSMutableDictionary * mutableDictionary = [NSMutableDictionary dictionaryWithStuff....];
NSDictionary * dictionary = mutableDictionary;
//from this point on, only use dictionary
虽然dictionary
技术上(内部)可变,但您将无法访问set
方法,因为这些方法是NSMutableDictionary
上的方法。
答案 2 :(得分:2)
如果我正确理解你的问题(鉴于你后来的评论),你想要将一个可变对象的不可变副本转换回可变的。
问题似乎是:
NSMutableString *foo = [NSMutableString stringWithString:@"a mutable object"];
NSMutableDictionary *dictionary1, *dictionary2;
dictionary1 = [NSMutableDictionary dictionaryWithObject:foo forKey:@"foo"];
dictionary2 = [[NSMutableDictionary alloc]initWithDictionary:dictionary1
copyItems: YES];
[[dictionary1 objectForKey:@"foo"] appendString:@", mutated"];
[[dictionary2 objectForKey:@"foo"] appendString:@", mutated"];
我们可以很好地改变dictionary1中的对象,但对dictionary2做同样的操作会引发异常。
这是因为虽然NSMutableDictionary的initWithDictionary:copyItems:方法生成了字典对象的可变副本,但它会为其内容创建不可变的副本。
区分不可变版本和不可变版本的类(例如cocoa的基本字符串,数组和字典类)应该实现copyWithZone:和mutableCopyWithZone:方法。由于并非所有类都实现了mutableCopyWithZone:方法,因此NSMutableDictionary的initWithDictionary:copyItems:方法可以不可变地复制每个dictionary1的内容,这意味着dictionary2包含不可变对象。
您可以通过发送mutableCopy消息来创建不可变对象的可变副本。但是对你来说可能更好的解决方案是将initWithDictionary:mutableCopyItems:方法添加到带有类别的NSMutableDictionary:
- (id) initWithDictionary:(NSDictionary *)otherDictionary
mutableCopyItems:(BOOL)flag
{
if (flag) {
self = [self init];
if (self)
for (id key in otherDictionary){
id object = [otherDictionary objectForKey:key];
if ([object respondsToSelector:@selector(mutableCopyWithZone:)])
[self setObject:[object mutableCopy] forKey:key];
else
[self setObject:[object copy] forKey:key];
}
}
else
self = [self initWithDictionary:otherDictionary];
return self;
}
如果你想知道copy,mutableCopy,copyWithZone:和mutableCopyWithZone之间的区别,请阅读这些: