PickerView crashes out EXC_BAD_ACCESS when moved
I have a pickerView, it appears in the Simulator but as soon as I try and scroll it, it crashes EXC_BAD_ACCESS in the main.m file.
I know it is to do with the arrays that I load in from a pList because when I try this with arrays that are initialised in the program it works (see commented out sections), is this something to do with 'nil' at the end of the array? If so how can I see this and how can I add it.
I appreciate any help on this please I'm pulling what's left of my hair out, and I'm fairly new to this...
// Method to define the numberOfComponent in a picker view.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
// Met开发者_Go百科hod to define the numberOfRows in a component using the array.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent :(NSInteger)component
{
if (component==0)
{
return [maximumSpeed count];
}
else
{
return[warningTime count];
}
}
//PickerViewController.m
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *stringToReturn = nil;
switch (component)
{
case 0:
stringToReturn = [maximumSpeed objectAtIndex:row];
break;
case 1:
stringToReturn = [warningTime objectAtIndex:row];
break;
}
return stringToReturn;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
// finding the path and loading the pList as a dictionary into 'data'
NSString *pListFile = [[NSBundle mainBundle] pathForResource:@"PropertyList" ofType:@"plist"];
data =[NSDictionary dictionaryWithContentsOfFile:pListFile];
// get and set up the 2 arrays
maximumSpeed = [data valueForKey:@"MaximumSpeed"];
warningTime = [data valueForKey:@"WarningTime"];
//maximumSpeed =[[NSArray alloc] initWithObjects:@"Running",@"Crying",@"Boring",@"Working",nil];
//warningTime = [[NSArray alloc] initWithObjects: @"Happy", @"Sad" , @"Good", @"joyce",nil];
NSLog(@"%@", maximumSpeed);
NSLog(@"%@", warningTime);
}
(void)viewDidUnload
{
[self setTxt1:nil];
[pickerView release];
pickerView = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[txt1 release];
[pickerView release];
[warningTime release];
[maximumSpeed release];
[super dealloc];
}
You do not own the object(s) returned by valueForKey
, in this case, your arrays. These objects are getting released and you end up with a dangling pointer. Hence, the crash. The problem is here:
maximumSpeed = [data valueForKey:@"MaximumSpeed"];
warningTime = [data valueForKey:@"WarningTime"];
You need to retain them.
maximumSpeed = [[data valueForKey:@"MaximumSpeed"] retain];
warningTime = [[data valueForKey:@"WarningTime"] retain];
The following works because you own the objects you create.
//maximumSpeed =[[NSArray alloc] initWithObjects:@"Running",@"Crying",@"Boring",@"Working",nil];
//warningTime = [[NSArray alloc] initWithObjects: @"Happy", @"Sad" , @"Good", @"joyce",nil];
This also applies to dictionaryWithContentsOfFile
:
data =[NSDictionary dictionaryWithContentsOfFile:pListFile];
You can retain (like before) or switch to the alloc-init
version:
data = [[NSDictionary dictionaryWithContentsOfFile:pListFile] retain];
// or
data = [[NSDictionary alloc] initWithContentsOfFile:pListFile];
You do not own the objects returned by methods unless the method name begins with "alloc", "new", "copy" or "mutableCopy".
As it has been said already, you could copy the objects (arrays) maximumSpeed and warningTime or, alternatively, you retain and release them.
Talking about releasing ... You are releasing pickerView twice. First in viewDidUnload and second in dealloc. It may actually work without a crash because you assign nil to it after the first release and therefore the second release should be processed without a crash anyway.
However, that indicates that you should be more careful about your memory management, retain-release-pairs in particular.
Why don't you track the zombies in the instrumemts application? You start it in xcode4 with cmd-i. In most cases that gives some useful hint on where to have a detailed look on missing retains (or copies).
精彩评论