NSMutableArray addObject: -[__NSArrayI addObject:]: unrecognized selector sent to instance

The synthesized setter for @property (copy) sends a copy message to the array, which results in an immutable copy.

You have no choice but the implement the setter yourself here, as detailed in the Objective-C guide.


As I was proof reading my post, a thought occurred to me and I answered my own question. This resolution was obscure enough that I decided to go ahead, create the post and answer it myself (so any other newbies, like myself, won't get hung up).

My mistake was in...

@property (copy) NSMutableArray *array;

it should have been...

@property (retain) NSMutableArray *array;

The error was not happening in the way I was executing my code, but rather in the way the anObject was attempting to "copy" the NSMutableArray array.

As we all know...

mutableArray = [mutableArray copy];

is not always (or ever, in my experience) equal to...

mutableArray = [mutableArray mutableCopy];

And this was the source of my problem. By simply switching the @property from (copy) to (retain) I solved my problem.


I would like to tip my hat to Georg Fritzsche. I did end up needing to use (copy) instead of (retain), and I would not have known what to do without his input.

//@property (copy) NSMutableArray *array;
@property (nonatomic, copy) NSMutableArray *array; //overridden method is non-atomic as it is coded and should be reflected here.

If you wish to use (copy) on a mutable object you must override the "setter" method as follows...

- (void)setArray:(NSArray *)newArray {

    if ( array != newArray ) { 
        [array release];
        array = [newArray mutableCopy];
//      [array retain]; // unnecessary as noted by Georg Fritzsche
    }

    return;
}

NOTE: You will get a compiler warning: Incompatible Objective-C types initializing 'struct NSArray *', expected 'struct NSMutableArray *' I chose to declare the newArray parameter as an (NSArray *), because you are given the flexibility to have any array passed and correctly copied to your (NSMutableArray *) variable. If you wish to declare the newArray parameter as an (NSMutableArray *) you will still need to leave the mutableCopy method in place to get your desired results.

Cheers to Georg! Z@K!