3

我一直在使用最优秀的 Accessorizer 为我在 Xcode 中的 Obj-C 代码自动神奇地生成 setter/getter。最近在 Accessorizer 中进行了更改:

旧版本的 Accessorizer:
@property (nonatomic, retain) NSMutableSet *setA;
@property (nonatomic, 保留) NSMutableSet *setB;

新版本的 Accessorizer:
@property (nonatomic, copy) NSMutableSet *setA;
@property (nonatomic, 复制) NSMutableSet *setB;

可悲的是,新版本使我的代码崩溃。在我的代码中,我执行以下操作:

self.setA = [[[NSMutableSet alloc] init] autorelease];
self.setB = [[[NSMutableSet alloc] init] autorelease];

// ...

[self.setA minusSet:self.setB];  

上面的代码行使用旧方式(保留)可以正常工作,但使用新方式(复制)会崩溃。显然这里出了点问题。我广泛依赖 Accessorizer。有人可以澄清在 NSMutableSet 的上下文中使用复制/保留的含义吗?

谢谢,
道格

4

2 回答 2

4

如果您的属性类型是可变集,则很可能需要保留。如果它是一个非可变集(又名 NSSet),Apple 的指导方针说使用复制而不是保留。

区别在于期望可变集会发生变化。一个非可变集应该保持不变,但如果它被声明为保留,有人可以将它设置为一个可变集,然后意外地更改内容。

于 2010-09-30T15:52:41.963 回答
4

是的,这是属性的“功能”。当您设置一个声明为 的属性时,copy生成的 setter 将-copy在该对象上调用。不幸的是,在可变对象的情况下,这会导致不可变的变体。

换句话说,返回的对象[myMutableSet copy]不可变的。

如果您需要 set 是可变的,那么您必须使用retain(或覆盖 setter 以使用mutableCopy而不是copy)。

我对此提交了一个错误(rdar://8416047),但它被关闭为“按设计工作”。(因为 setter 真的没有办法知道一个对象是否可变)

于 2010-09-30T15:57:03.453 回答