NSMutableArray addObject: -[__NSArrayI addObject:]: unrecognized selector sent to instance
IphoneNsmutablearrayIphone Problem Overview
I have tried to initialize my NSMutableArray 100 ways from Sunday, and NOTHING is working for me. I tried setting it equal to a newly allocated and initialized NSMutableArray, just allocating, initializing the variable by itself, every combination I could think of and always the same result.
Here's the code:
Object.h
NSMutableArray *array;
@property (copy) NSMutableArray *array;
Object.m
@synthesize array;
if ( self.array ) {
[self.array addObject:anObject];
}
else {
self.array = [NSMutableArray arrayWithObjects:anObject, nil];
}
NOTE: In debug "anObject" is NOT nil at time of execution...
I have tested anObject and it isThe initialization works just fine, but I keep getting the error below when I try to addObject: to self.array.
> 2010-07-10 11:52:55.499 MyApp[4347:1807] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x184480 > > 2010-07-10 11:52:55.508 MyApp[4347:1807] *** Terminating app due to uncaught exception > 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x184480'
Does anyone have any idea what's going wrong?
Iphone Solutions
Solution 1 - Iphone
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.
Solution 2 - Iphone
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.
Solution 3 - Iphone
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!
Solution 4 - Iphone
Have some indexes (into a data array elsewhere) and wanted to have them in numerical order (for a good reason). Crashing until added mutableCopy at the end. Totally puzzled, until I recalled that using Objective-C literal @[] returns a non-mutable array.
NSMutableArray *a = [@[@(self.indexA), @(self.indexB)] mutableCopy];
NSLog(@"%@", a);
[indexArray sortUsingComparator: ^(NSNumber *obj1, NSNumber *obj2) {
return [obj1 compare:obj2];
}];
NSLog(@"%@", a);
Thanx, Zak!
Solution 5 - Iphone
I was getting the same error, even though my properties were strong (using ARC) and I allocated the array with NSMutableArray.
What was happening was that I was archiving the mutable array (as it contains custom objects) for future use and when decoding it, it returns an immutable copy.
Hope it helps anyone out there.
Solution 6 - Iphone
The error came about as a result of attempting to add an object to an NSMutableArray type that was actually pointing to an NSArray object. This type of scenario is shown in some demo code below:
NSString *test = @"test";
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
[mutableArray addObject:test];
NSArray *immutableArray = [[NSArray alloc] init];
mutableArray = immutableArray;
[mutableArray addObject:test]; // Exception: unrecognized selector
From the above code, it is easy to see that a subclass type is being assigned to a superclass type. In Java, for instance, this would immediately have been flagged as an error (conversion error between types), and the problem resolved fairly quickly. To be fair to Objective-C, a warning is given when attempting to perform an incompatible assignment, however, this simply just does not seem to be enough sometimes and the result can be a real pain for developers. Fortunately, this time around, it was not myself who bore most of this pain :P
Solution 7 - Iphone
I got bitten by this exception for a typo I've made, maybe it'll save someone 5 min. of their time:
I wrote:
NSMutableArray *names = [NSArray array];
instead of:
NSMutableArray *names = [NSMutableArray array];
The compiler has no problem with that because NSMutableArray is also an NSArray, but it crashes when trying to add an object.
Solution 8 - Iphone
I had similar error saying : unrecognized selector sent to instance for NSMutable array.. After going through a lot of things, I figured out that I was using my mutable array as a property as
@property (assign, nonatomic) NSMutableArray *myMutableArray;
while copy pasting and not paying attention and it was causing the problem.
The solution us that I changed it to strong type(you can change it to any other type like strong/weak,etc.. depending your requirement). So solution in my case was :
@property (strong, nonatomic) NSMutableArray *myMutableArray;
So, be careful while copy pasting! Do check once.
Solution 9 - Iphone
This exception can happen if one of the objects in the array is null.