Search code examples
objective-cioscocoa-touchuiviewcontrolleruipickerview

Error when returning [anArray count] in numberOfRowsInComponent in UIPickerView


I have a UIViewController that has a UIPickerView and UITableView. The UIPicker has 3 components.

When I try to define the number of components in each array by returning [anArray count], the program freezes without throwing an error when loading the UIViewController.

When I put NSLogs in viewDidLoad: for [self.hours count], [self.minutes count], and [self.meridiem count], the correct number of values are returned.

- (void)viewDidLoad {

[super viewDidLoad];

NSMutableArray *tempHours = [NSMutableArray array];
for (NSInteger i = 0; i < 12; i++) [tempHours addObject:[NSNumber numberWithInteger:(i+1)]];
self.hours = [NSArray array];
hours = tempHours;
[tempHours release];

NSMutableArray *tempMinutes = [NSMutableArray array];
for (NSInteger i = 0; i <= 59; i++) [tempMinutes addObject:[NSNumber numberWithInteger:i]];
self.minutes = [NSArray array];
minutes = tempMinutes;
[tempMinutes release];

NSMutableArray *tempMeridiem = [NSMutableArray array];
for (NSInteger i = 0; i <= 1; i++) [tempMeridiem addObject:[NSNumber numberWithInteger:i]];
self.meridiem = [NSArray array];
meridiem = tempMeridiem;
[tempMeridiem release];

}

Now, in pickerView:numberOfRowsInComponent:Component:, the code freezes without an error if I try to output [anArray count](where anArray is a placeholder for hours, minutes, and meridiem). If I set numberOfRows to an integer value, or to component+1 everything works just fine.

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {

NSInteger numberOfRows;

if (component == 0) {
    // numberOfRows = component+1;
    numberOfRows = [self.hours count];
}
else if(component == 1) { 
    // numberOfRows = component+1;
    numberOfRows = [self.minutes count];
}
else { 
    // numberOfRows = component+1;
    numberOfRows = [self.meridiem count];
}

return numberOfRows;

}

I have a feeling my NSArrays (hours, minutes, meridiem) aren't being retained, but running the Analyzer doesn't show me that I have any memory leaks in that ViewController.

Any and all help would be greatly appreciated!


Solution

  • You are creating unnecessary arrays and not retaining the ones that count. See your code:

    self.hours = [NSArray array]; 
    hours = tempHours; 
    [tempHours release];
    

    Here you created an autoreleased array and set it to your self.hours property (which hopefully has a retain keyword attached to it). But then the very next line you access the ivar directly and set it to tempHours. Then you send a release message to tempHours without having ever retained it. Since tempHours is autoreleased it will magically disappear on the next drain of the auto release pool. I believe what you wanted to do is:

    self.hours = tempHours;
    

    Ditto for your other array collections.