开发者

What are the semantics of using retain vs. copy for a property of type NSMutableSet;

开发者 https://www.devze.com 2023-01-18 11:27 出处:网络
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:

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:

old version of Accessorizer:

@property (nonatomic, retain) NSMutableSet *setA;

@property (nonatomic, retain) NSMutableSet *setB;

new version of Accessorizer:

@property (nonatomic, copy) NSMutableSet *setA;

@property (nonatomic, copy) NSMutableSet *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?

Thanks,

Doug


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.

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.


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.

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

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

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)

0

精彩评论

暂无评论...
验证码 换一张
取 消