views:

617

answers:

5

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:

@property (readwrite, copy) NSMutableArray *myArray;

Is there any reason that Apple didn't implement the following syntax?

@property (readwrite, mutablecopy) NSMutableArray *myArray;

Since we don't have mutablecopy, what's the best way to handle this (seemingly common) situation? Should I just write my own setter that does a -mutableCopy?

+1  A: 

You'll have to write your own setter.

Brent Royal-Gordon
+4  A: 

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];
    }
}
Markus Müller
+3  A: 

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.

Marc Charbonneau
+4  A: 

It's not common to pass around NSMutableArrays 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:

  1. Key-value observing works as expected (there are several cases where observing an NSMutableArray leads to not-what-you-want behavior)
  2. The implementation of your data structure is hidden because you expose mutating methods (e.g. -[MyObject insertObjectInMyProperty:(id)newObject atIndex:(NSUInteger)i] , not the data structure itself.
Barry Wark
+4  A: 

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.

wbyoung