2011-08-24 83 views
2

我有一个pickerView,它出现在模拟器中,但只要我尝试并滚动它,就会在main.m文件中崩溃EXC_BAD_ACCESS。PickerView在移动时崩溃EXC_BAD_ACCESS

我知道这是与我从pList加载的数组有关的,因为当我在程序中初始化的数组尝试这个数组时,它是如何处理的'无'在阵列的末尾?如果是这样,我怎么能看到这个,我怎么能添加它。

我感谢有这方面的帮助,请我拉着还剩下些什么我的头发,我是相当新的这个...

// 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]; 
} 

回答

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”开头。

+0

非常感谢Thankyou,我很感谢你在回答时间和它的工作。它恰好是我读这篇文章http://stackoverflow.com/questions/2426651/pickerview-exc-bad-access - 这是同样的问题。我在界面中声明了这些变量,但我想这并不能使它们成为全局变量。 – John67

+0

@ John67欢迎您:) – albertamg

0

正如已经说过的,您可以复制对象(数组)maximumSpeed和warningTime,或者保留并释放它们。

谈到释放...你释放pickerView两次。首先在viewDidUnload中,第二个在dealloc中。它实际上可以在没有崩溃的情况下工作,因为您在第一次发布之后将nil分配给它,因此无论如何应该处理第二个发行版而不会崩溃。

但是,这表明你应该更加小心你的内存管理,特别是保留 - 释放 - 对。

为什么不跟踪instrumemts应用程序中的僵尸?你使用cmd-i在xcode4中启动它。 在大多数情况下,对于在何处详细查看遗漏保留(或副本)提供了一些有用的提示。

+0

感谢Hermann,内存管理是我知道我需要关注的一个领域 - 我尝试了僵尸程序,看起来我也需要学习它!如果它能告诉我变量的名字,这将是有用的。 – John67

+0

约翰,它不仅告诉你变量。它为您提供了alloc/retain/release历史的详细视图。这不仅是分析的好工具。它有助于理解所有这些自动释放机制。谷歌的一些说明。 –