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

IphoneNsmutablearray

Iphone 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZakView Question on Stackoverflow
Solution 1 - IphoneGeorg FritzscheView Answer on Stackoverflow
Solution 2 - IphoneZakView Answer on Stackoverflow
Solution 3 - IphoneZakView Answer on Stackoverflow
Solution 4 - IphoneJOMView Answer on Stackoverflow
Solution 5 - IphoneolivaresFView Answer on Stackoverflow
Solution 6 - IphoneBaljeet SinghView Answer on Stackoverflow
Solution 7 - IphonemarmorView Answer on Stackoverflow
Solution 8 - IphonePriyankaView Answer on Stackoverflow
Solution 9 - Iphoneho322View Answer on Stackoverflow