可变为不可变对象

时间:2010-09-02 09:15:27

标签: cocoa

有没有办法在可可中将可变对象转换为不可变对象? 我使用过NSMutableDictionary * mut = [[NSMutableDictionary alloc] initWithDictionary:copyItems:]; 但是这个字典在许多其他地方使用而没有可变的东西。

最诚挚的问候, Subrat

3 个答案:

答案 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之间的区别,请阅读这些:

http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Protocols/NSMutableCopying_Protocol/Reference/Reference.html#//apple_ref/occ/intf/NSMutableCopying

http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Protocols/NSCopying_Protocol/Reference/Reference.html#//apple_ref/occ/intf/NSCopying