I have an Obj-C 2.0 class that has an NSMutableArray property. If I use the following code, then the synthesised setter will give me an immutable copy, not a mutable one:
Keep in mind that passing around a mutable array isn't really a common practice in Cocoa. You might use a private mutable array as internal storage, but create methods using plain NSArray objects to add or get objects out of it. This may be why there's no mutablecopy property declaration.
As said before, the right way to do it is not to make the mutable array a property. There's a great explanation of what you should implement to be KVC compliant here.
The right way to hold on to a NSMutableArray is with a retain property:
@property (nonatomic, retain) NSMutableArray *myArray;
You do not need to write your own setter or use copy. The copy property should be used with a NSArray that actually does need to be copied when the property is captured into another object. For example, if you assign a NSMutableArray object to a property that is of type NSArray with the copy property, then you do want to make a copy of the mutable array to "capture" it as an immutable property from that point forward.
And Marc has the right approach, one would not normally make NSMutableArray a part of the public API of your objects. If you do have a public property, it can be a NSArray with the copy property.
It's not common to pass around NSMutableArray
s in Cocoa. Standard Cocoa practice would be to implement the key-value coding compliant methods for an indexed to-many property. This has two benefits:
-[MyObject insertObjectInMyProperty:(id)newObject atIndex:(NSUInteger)i]
, not the data structure itself.I ran into the same problem some time ago and found a document on the Apple Developer Connection recommending to provide your own implementation of the setter. Code sample form the linked document:
@interface MyClass : NSObject {
NSMutableArray *myArray;
}
@property (nonatomic, copy) NSMutableArray *myArray;
@end
@implementation MyClass
@synthesize myArray;
- (void)setMyArray:(NSMutableArray *)newArray {
if (myArray != newArray) {
[myArray release];
myArray = [newArray mutableCopy];
}
}
You'll have to write your own setter.