nintandrew
nintandrew

Reputation: 115

Objective C Dealocating Properties

I've been working on implementing MVC into this application I've been teaching myself programming with, and I've been running into EXC_BAD_ACCESS errors for the past couple days. I've been reading quite a bit and I have found debugger settings that have led me to find that when I make a call from my controller object on a property of my model object, I'm told a retain message is being sent to an already deallocated instance. I know the line a bad access error is shown on isn't always where the error is, but by commenting out lines, I think I've found the spot.

I'm using my AppDelegate class as my controller, and the following function is called when a button is pressed:

- (IBAction)makeChart:(id)sender {

[self.myModel makeCodesandNamesArray:self.popupButton.indexOfSelectedItem];

NSLog(@"%@",[self.myModel.CodesandNames objectAtIndex:3]);

[sender setEnabled:NO];

NSLog(@"Done!!");}

In my model class, I have the makeCodesandNamesArray method:

-(void)makeCodesandNamesArray:(long)popvalue{


NSString *codesNames = [[NSString alloc] init];
switch ((int)popvalue) {
    case 0:
        codesNames = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource: @"NEWD65Lab" ofType: @"txt"] encoding:NSUTF8StringEncoding error:NULL];
        break;

    case 1:
        codesNames = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource: @"NEWD50Lab" ofType: @"txt"] encoding:NSUTF8StringEncoding error:NULL];
        break;

    case 2:
        codesNames = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource: @"NEWALab" ofType: @"txt"] encoding:NSUTF8StringEncoding error:NULL];
        break;
    case 3:
        codesNames = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource: @"NewCodesandNames" ofType: @"txt"] encoding:NSUTF8StringEncoding error:NULL];
        break;
    default:
        NSLog(@"Selection Index outside bounds of popup somehow");
        break;
}

NSArray *colorArray = [[NSArray alloc]initWithArray:[codesNames componentsSeparatedByString:@"\n"]];

self.CodesandNames = colorArray;}

I have the @property for CodesandNames in the header file of the model and I've connected the model to the controller correctly as far as I can tell.

My error shows up with the NSLog in the controller, and the debugger is telling me that "[__NSArrayI retain]: message sent to deallocated instance 0x1e0112200". I haven't been able to find the specific instance 0x1e0112200, but when I comment out the NSLog, I don't get this error. I have also had other method calls within the controller action that use the CodesandNamesproperty as a parameter and get the same error.

It seems like the property is being deallocated between defining it and trying to call it in the NSLog, but I don't see anything that could be doing it.

I have also had the makeCodesandNamesArray in the model return the colorArray and set it to self.myModel in the controller, but the same error happened. Lastly, when I had makeCodesandNamesArray return the colorArray and called it in the NSLog, there was no error and the array displayed fine.

Any help with this problem would be greatly appreciated, thanks!

Upvotes: 0

Views: 74

Answers (1)

Tiago Almeida
Tiago Almeida

Reputation: 14237

With the information you gave us the problem most likely is in your property declaration.

Your array should be, in this case a strong property. Therefore, make sure you are declaring your array like this:

@property(nonatomic, strong) NSArray* CodesandNames;

For more information on strong vs weak please check this answer on stackoverflow.

Additionally please be aware of code standards. Your properties/iVars should start with a lower case char.

At last, allow me to suggest changing that switch to this:

NSDictionary *popValueToCodeName = @{@(0) : @"NEWD65Lab",
                                     @(1) : @"NEWD50Lab",
                                     @(2) : @"NEWALab",
                                     @(3) : @"NewCodesandNames";

if(popValueToCodeName[@((int)popValue)]) {
    [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource: popValueToCodeName[@((int)popValue)] ofType: @"txt"] 
                                     encoding:NSUTF8StringEncoding 
                                        error:NULL];
} else {
     NSLog(@"Selection Index outside bounds of popup somehow");
}

Upvotes: 1

Related Questions