2011-08-24 80 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歷史的詳細視圖。這不僅是分析的好工具。它有助於理解所有這些自動釋放機制。谷歌的一些說明。 –