iPhone - Crash using addObject on a NSMutableArray

依然范特西╮ 提交于 2019-11-28 11:36:56

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;
}

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;
}

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.

What does your init method look like? It should look something like this...

- (id)init
{
    self = [super init];

    self.param = [NSMutableArray array];

    return self;
}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!