简体   繁体   中英

Why do I get SIGABRT when trying to addObject to NSMutableArray

I have two classes - BNRItem and BNRContainer. BNRContainer is a subclass of BNRItem. In order to cut down the amount of code I paste, assume the following that I have tested and know works:

+(BNRItem * ) randomItem; // allocate and init a random item.

@property(nonatomic, readwrite, copy) NSMutableArray * subitems; // This is a property of BNRContainer class

main.m:

NSMutableArray * rand_items = [NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
    [rand_items addObject: [BNRItem randomItem]];
}

[rand_items addObject: @"HELLO"];

BNRContainer * rand_container_of_items = [BNRContainer randomItem];
rand_container_of_items.subitems = rand_items;

[rand_container_of_items.subitems addObject: @"THERE"]; // ERROR SIGABRT

NSLog(@"------------------------------------------------------");
NSLog(@"%@", rand_container_of_items);

rand_container_of_items = nil;

If I NSLog without adding @"THERE", I see "HELLO" in my description so I know that I am able to call addObject: at that point. Why do I get SIGABRT when I am trying to access ivar "subitems" of rand_container_of_items? I just can't figure this one out.

The problem seems to be the copy modifier in your declaration.

@property (nonatomic, readwrite, copy) NSMutableArray *subitems;

In the documentation , the NSCopying protocol conformance is inherited form NSArray, so my suspicion is that in this line

rand_container_of_items.subitems = rand_items;

subitems contains an immutable copy of the original array. Try removing copy from your declaration. If you need a copy use the mutableCopy method.

Problem lies here

property(nonatomic, readwrite, copy) NSMutableArray * subitems;

You should not use copy here since it will return immutable copy of the object. So that you cannot add objects to it. It could be

property(nonatomic, strong) NSMutableArray * subitems;

This line is giving sigbart as when you allocate an array to mutable array, it becomes mutable.

So, when you are copying rand_items to rand_container_of_items.subitem, it is becoming mutable.

So, to make it immutable, try following :

BNRContainer * rand_container_of_items = [BNRContainer randomItem];
rand_container_of_items.subitems = [rand_items mutablecopy];

[rand_container_of_items.subitems addObject:@"THERE"]; // ERROR SIGABRT

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM