iPhone - Crash using addObject on a NSMutableArray

前端 未结 5 1526
悲哀的现实
悲哀的现实 2020-12-10 19:42

I have a problem here. Or Maybe I\'m really tired...

I have a class :

@interface THECLASS : UIViewController  {
    NSMuta         


        
相关标签:
5条回答
  • 2020-12-10 19:54

    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;
    }
    
    0 讨论(0)
  • 2020-12-10 20:04

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

    - (id)init
    {
        self = [super init];
    
        self.param = [NSMutableArray array];
    
        return self;
    }
    
    0 讨论(0)
  • 2020-12-10 20:11

    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;
    }
    
    0 讨论(0)
  • 2020-12-10 20:18

    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.

    0 讨论(0)
  • 2020-12-10 20:21

    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.

    0 讨论(0)
提交回复
热议问题