对于类型为nsmutable et的属性使用retain和copy的语义是什么?

时间:2022-09-07 10:50:38

I have been using the most excellent Accessorizer to auto-magically generate setters/getters for my Obj-C code in Xcode. Recently a change was made in Accessorizer:

我一直在使用最优秀的Accessorizer在Xcode中自动为我的object - c代码生成setter /getter。最近,配饰商有了变化:

old version of Accessorizer:
@property (nonatomic, retain) NSMutableSet *setA;
@property (nonatomic, retain) NSMutableSet *setB;

旧版本的Accessorizer: @property(非原子的,保留的)nsmutable et *setA;@property (nonatomic, retain) nsmutabet *setB;

new version of Accessorizer:
@property (nonatomic, copy) NSMutableSet *setA;
@property (nonatomic, copy) NSMutableSet *setB;

新版本的Accessorizer: @property(非原子的,拷贝的)nsmutable et *setA;@property (nonatomic, copy) nsmu汤匙et *setB;

Sadly, the new version crashes my code. In my code I do the following:

不幸的是,新版本崩溃了我的代码。在我的代码中,我做如下工作:

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

// ...

/ /……

[self.setA minusSet:self.setB];  

The above line of code works fine using the old way (retain) but crashes using the new way (copy). Clearly something is wrong here. I rely on Accessorizer extensively. Could someone please clarify the implications of using copy/retain in the context of NSMutableSet?

上面这行代码使用旧的方法(保留)可以正常工作,但是使用新方法(复制)就会崩溃。显然这里出了问题。我广泛使用配饰。是否有人可以澄清使用复制/保留在nsmuet的上下文中的含义?

Thanks,
Doug

谢谢,道格

2 个解决方案

#1


4  

If you're property type is a mutable set, you most likely want a retain. If it's a non-mutable set (aka NSSet), Apple's guidelines say to use copy rather than retain.

如果您的属性类型是一个可变集,那么您很可能需要一个retain。如果它是一个非可变集(即NSSet),那么苹果的指导方针是使用copy而不是retain。

The distinction is that there's an expectation that a mutable set is going to change. A non mutable set is expected to remain unchanged, but if it's declared as retain, someone could set it to a mutable set and then change the contents unexpectedly.

区别在于,有一个期望可变集会改变。一个非可变的集合被期望保持不变,但是如果它被声明为retain,某人可以将它设置为一个可变的集合,然后意外地更改内容。

#2


4  

Yes, this is a "feature" of properties. When you set a property that's declared as copy, then the generated setter is going to invoke -copy on the object. Unfortunately, in the case of mutable objects, this results in an immutable variant.

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

In other words, the object returned by [myMutableSet copy] is not mutable.

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

If you need the set to be mutable, then you must use retain (or override the setter to use mutableCopy instead of copy).

如果您需要设置为可变的,那么您必须使用retain(或者重写setter来使用mutableCopy而不是复制)。

I filed a bug on this (rdar://8416047), but it was closed as "works as designed". (Because there's really no way for the setter to know if an object is mutable or not)

我在这上面提交了一个bug (rdar://8416047),但是它被关闭了,因为它是“设计的工作”。(因为setter无法知道对象是否可变)

#1


4  

If you're property type is a mutable set, you most likely want a retain. If it's a non-mutable set (aka NSSet), Apple's guidelines say to use copy rather than retain.

如果您的属性类型是一个可变集,那么您很可能需要一个retain。如果它是一个非可变集(即NSSet),那么苹果的指导方针是使用copy而不是retain。

The distinction is that there's an expectation that a mutable set is going to change. A non mutable set is expected to remain unchanged, but if it's declared as retain, someone could set it to a mutable set and then change the contents unexpectedly.

区别在于,有一个期望可变集会改变。一个非可变的集合被期望保持不变,但是如果它被声明为retain,某人可以将它设置为一个可变的集合,然后意外地更改内容。

#2


4  

Yes, this is a "feature" of properties. When you set a property that's declared as copy, then the generated setter is going to invoke -copy on the object. Unfortunately, in the case of mutable objects, this results in an immutable variant.

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

In other words, the object returned by [myMutableSet copy] is not mutable.

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

If you need the set to be mutable, then you must use retain (or override the setter to use mutableCopy instead of copy).

如果您需要设置为可变的,那么您必须使用retain(或者重写setter来使用mutableCopy而不是复制)。

I filed a bug on this (rdar://8416047), but it was closed as "works as designed". (Because there's really no way for the setter to know if an object is mutable or not)

我在这上面提交了一个bug (rdar://8416047),但是它被关闭了,因为它是“设计的工作”。(因为setter无法知道对象是否可变)