I have a problem here. Or Maybe I\'m really tired...
I have a class :
@interface THECLASS : UIViewController {
NSMuta
Your property is defined as retain
, and you say that param
is "a filled array from the caller view". This could be your problem.
For example, if you do the following:
NSArray * filledArray = [NSArray arrayWithObjects:..., nil];
theClassInstance.param = filledArray;
You will have retained a non-mutable array.
Edit: To debug the setting of param
, you could do the following in your .m:
@dynamic param;
- (NSMutableArray*)param { return param; }
- (void)setParam:(NSMutableArray*)newArray {
NSLog(@"setting new param from class: %@",
NSStringFromClass([newArray class]));
[newArray retain];
[param release];
param = newArray;
}
What does your init method look like? It should look something like this...
- (id)init
{
self = [super init];
self.param = [NSMutableArray array];
return self;
}
Answer is buried in the comments to the "accepted" answer. I came here from Google and it fixed my problem, so ... to make it clearer, based on @e.James's comment:
When you implement the "NSCopying" protocol, and implement "copyWithZone", you MUST NOT use "copy" on your internal mutable arrays - this DOES NOT copy the array (instead, it creates a non-mutable copy).
e.g. from my own code:
// Class: MyClass
@property(nonatomic, retain) NSMutableArray* mutArray;
-(id)copyWithZone:(NSZone *)zone
{
MyClass* other = [[MyClass alloc] init];
// other.mutArray = [self.mutArray copy]; // WRONG!
other.mutArray = [self.mutArray mutableCopy]; // CORRECT!
return other;
}
After struggling a lot i found the solution for my problem. In my case the problem was,
I have a mutable dictionary and array
@property(strong,nonatomic)NSMutableDictionary *dictInfo;
@property(retain,nonatomic) NSMutableArray *userAccountsList;
And I am adding server array list to userAccountsList array like this
self.dictInfo = [jsonObject valueForKey:@"customerAccountList"];
I have taken another array and adding server array list to that array
array = [self.dictInfo valueForKey:@"banker"];
and finally adding array to userAccountsListArray like this
userAccountsList = [NSMutableArray arrayWithArray:array];
And here adding additional object to array
[userAccountsList addObject:@"Other Account"];//I was getting error here.
[tableViewObj reloadData];
Hope it helps someone. Please vote up if it helps.
For some reason you're calling the addObject:
method on an instance of NSArray
, as the stack trace indicates. Perhaps the synthesized getter of your param
object returns an NSArray
? Don't use the getter in your method:
- (void) changedSelectorValue:(NSIndexPath*)indexPath isOn:(BOOL)isOn {
[param addObject:@"eeeee"];
}
Ultimately, the error is correct. You're calling a mutating method on an immutable object. Strange enough, in my testing this doesn't cause a compiler error or warning:
NSMutableArray *array = [[NSArray alloc] init];
Edit: Whether you want to believe it or not, somehow the param
ivar is being set to an instance of an NSArray. Override the setter:
- (void)setParam:(NSMutableArray *)p {
if (param != p) {
[param release];
param = [p retain];
}
}
Then add a breakpoint on that method, and check to see when an NSArray is being passed in.