我有一个pickerView,它出现在模拟器中,但是当我尝试滚动它时,它会在main.m文件中崩溃EXC_BAD_ACCESS。
我知道这是关于我从pList加载的数组,因为当我尝试使用在程序中初始化的数组时它会工作(参见注释掉的部分),这是否与'nil'有关在数组的末尾?如果是这样,我怎么能看到这个以及如何添加它。
我很感激任何有关这方面的帮助,请将我头发留下的东西拉出来,我对此很新...
// Method to define the numberOfComponent in a picker view.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
// Method 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];
}
答案 0 :(得分:5)
您不拥有valueForKey
返回的对象,在本例中是您的数组。这些对象正在被释放,你最终会有一个悬空指针。因此,崩溃。问题出在这里:
maximumSpeed = [data valueForKey:@"MaximumSpeed"];
warningTime = [data valueForKey:@"WarningTime"];
你需要保留它们。
maximumSpeed = [[data valueForKey:@"MaximumSpeed"] retain];
warningTime = [[data valueForKey:@"WarningTime"] retain];
以下情况有效,因为您拥有自己创建的对象。
//maximumSpeed =[[NSArray alloc] initWithObjects:@"Running",@"Crying",@"Boring",@"Working",nil];
//warningTime = [[NSArray alloc] initWithObjects: @"Happy", @"Sad" , @"Good", @"joyce",nil];
这也适用于dictionaryWithContentsOfFile
:
data =[NSDictionary dictionaryWithContentsOfFile:pListFile];
您可以保留(像以前一样)或切换到alloc-init
版本:
data = [[NSDictionary dictionaryWithContentsOfFile:pListFile] retain];
// or
data = [[NSDictionary alloc] initWithContentsOfFile:pListFile];
除非方法名称以“alloc”,“new”,“copy”或“mutableCopy”开头,否则您不拥有方法返回的对象。
答案 1 :(得分:0)
如前所述,您可以复制对象(数组)maximumSpeed和warningTime,或者保留并释放它们。
谈论释放......你发布了两次pickerView。首先是viewDidUnload,第二个是dealloc。它实际上可以在没有崩溃的情况下工作,因为你在第一次发布之后为它分配了nil,因此无论如何都应该处理第二个版本而不会发生崩溃。
但是,这表明您应该更加小心内存管理,特别是保留释放对。
为什么不跟踪instrumemts应用程序中的僵尸?你用cmd-i在xcode4中启动它。 在大多数情况下,它提供了一些有用的提示,可以详细了解丢失的保留(或副本)。