2010-03-17 27 views
3

我是iphone開發的新手,我一直在掙扎着前兩天我得到的EXC_BAD_ACCESS錯誤。我基本上採取斯坦福iphone類獨立,我想傳遞一個NSManagedObjects數組到一個應該顯示它們的TableViewController。應用程序在模擬器中啓動,並在tableView中顯示數據,但它會立即通過EXC_BAD_ACCESS出錯。從NSZombieEnabled獲取EXC_BAD_ACCESS沒有任何有用信息

我遵循這裏和其他地方的說明如何使用NSZombieEnabled來識別過早發佈的對象,但是這個來沒有任何有用的消息,即使NSZombieEnabled。我的猜測是它必須是由試圖訪問未通過release/autorelease釋放的未分配內存引起的。否則它會被視爲殭屍對象,就像我已經能夠修復的其他錯誤一樣。我不是c專家,但是這意味着如果我要聲明一個對象併發送消息而沒有實例化它,那麼這可能會發生嗎?我查看了我的代碼,看看我是否有類似的東西,然後空着。

我在調試器中有堆棧跟蹤,但我不確定如何使用它。我有點沮喪,因爲我不能在代碼中使用斷點來進一步縮小問題的範圍,因爲它似乎發生在應用程序加載完成後。我認爲如果沒有可能的用戶交互,應用程序將保持閒置狀態。是否在負載的尾端發生故障,我不能輕易看到它,或者在完成加載後在後臺執行某些操作。我非常感謝有關如何閱讀堆棧跟蹤的任何提示。

我輸入了我下面的堆棧跟蹤(無法弄清楚如何將它從調試器複製)

0 objc_msgSend
1 ??
2 -[NSManagedObject dealloc]
3 -[_PFManagedObjectReferenceQueue _processReferenceQue:]
4 _performRunLoopAction
5 ___CFRunLoopDoObservers
6 CFRunLoopRunSpecific
7 CFRunLoopRunInMode
8 GSEventRunModal
9 GSEventRun
10 UIApplicationMain
11 main

而且我在程序的兩大類是頂級的委託類和它調用的ViewTableController。

` - (無效)的applicationDidFinishLaunching:(UIApplication的*)應用{

self.tabBarController = [[[UITabBarController alloc] init] autorelease];   

UINavigationController *contactsNavigationController = [[self createContactsNavigationController] retain]; 

//UINavigationController *recentsNavigationController = [[self createRecentsNavigationController:photos] retain]; 

tabBarController.viewControllers = [[NSArray alloc] initWithObjects: contactsNavigationController, nil]; 

[contactsNavigationController release]; 
//[recentsNavigationController release]; 

[window addSubview:tabBarController.view]; 
    [window makeKeyAndVisible]; 

}

- (UINavigationController的*)createContactsNavigationController {

UINavigationController *contactsNavigationController = [[UINavigationController alloc] init]; 

UITabBarItem *contactsTabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem: UITabBarSystemItemContacts tag:0]; 
contactsNavigationController.tabBarItem=contactsTabBarItem ; 
[contactsTabBarItem release]; 


PersonListViewController *personListViewController = [[PersonListViewController alloc] initWithStyle:UITableViewStylePlain];  

NSManagedObjectContext *context = [self managedObjectContext]; 
personListViewController.managedObjectContext=context; 

personListViewController.contacts = [self createContacts]; 
[context release]; 

[email protected]"Contacts"; 

[contactsNavigationController pushViewController:personListViewController animated:false]; 
return [contactsNavigationController autorelease]; 

}`

` - (NSArray *)readContacts {

NSString *path = [[NSBundle mainBundle] bundlePath]; 

NSString *filePath = [path stringByAppendingPathComponent:@"FakeData.plist"]; 
NSArray *plist = [[NSMutableArray arrayWithContentsOfFile:filePath] retain]; 

return [plist autorelease]; 
} 

- (NSMutableArray *)createContacts { 

NSArray * plist = [[self readContacts] retain 
NSMutableArray *contactNames = [[NSMutableArray alloc] init]; 
NSMutableArray *contacts = [[NSMutableArray alloc] init]; 
for (NSDictionary *photo in plist) { 
    NSString *contactName = [photo objectForKey:@"user"]; 
    Person *contact = nil; 
    if (![contactNames containsObject:contactName]) { 
     contact = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext]; 
     contact.name =contactName; 
     NSError *error; 
     if (![managedObjectContext save:&error]) { 
      NSLog(@"SHIT the save person FAILED!!! %@",error); 
     } 

     [contacts addObject:contact]; 
     [contactNames addObject:contactName]; 



    } else { 
     contact = [contacts objectAtIndex:[contactNames indexOfObject:contactName]]; 
    } 

    [contactName release]; 

    Photo *image = (Photo *)[NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:managedObjectContext]; 

    image.imageFile = [photo objectForKey:@"path"]; 
    image.imageName = [photo objectForKey:@"name"]; 
    image.owner = contact; 

    contact.photos = [NSSet setWithObjects:image,nil]; 


    NSError *error; 
    if (![managedObjectContext save:&error]) { 
     NSLog(@"SHIT the save photoFAILED!!! %@",error); 
    } 

    [image release]; 
    [contact release]; 
} 

[plist release]; 

return [contacts autorelease]; 
} 

我很抱歉如果我的代碼太糟糕了,無法閱讀。

感謝您的幫助球員。

+0

你能告訴我們回溯和與之相關的代碼嗎? –

回答

7

這裏是你的問題:

NSString *contactName = [photo objectForKey:@"user"]; 
... a bunch of lines later 
[contactName release]; 

objectForKey:返回autoreleased對象,你不應該將其釋放。

同樣,insertNewObjectForEntityForName:inManagedObjectContext:managedObjectContext返回autoreleased對象,所以刪除[image release][contact release]

+0

我不知道該說些什麼。你是一個拯救生命的人。所以如果我理解這個權利,我的[contactName release]沒有拋出異常,因爲我仍然有一個自動釋放對象的retainCount爲1,但是一旦池被清除,自動釋放失敗,因爲我已經設置了它retainCount爲0.如果我沒有清除池的位置,或者只是需要更好地管理我的內存,我怎麼能在將來發現這樣的錯誤?對不起,我來自Java世界,我有點沮喪。不過謝謝。那太棒了。 – Nefsu

+1

首先,好的工作,你在這個評論中的解釋是正確的。第二,通過一些練習,你會變得更好。規則 如果你看到alloc或copy,你必須看到一個平衡的版本。否則,它是自動釋放的,所以除非你想保留它(保留),否則你不必做任何事情。 對於查找autorelease錯誤,有一件事可以幫助更大的代碼庫添加NSAutoreleasePools。例如: NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //做一些東西 [pool drain]; 現在你會崩潰在-drain上,這會讓你很明顯地崩潰。 –

+0

謝謝。我已經看到了本地池的示例代碼。我會給它一個鏡頭。再次感謝。 – Nefsu

0

我也越來越不EXC_BAD_ACCESS即使NSZombieEnabled被檢查任何有用的信息。所以,我想分享這個經驗:

經過幾個小時的模擬器苦苦掙扎,我決定把它安裝到設備上。從設備調試中獲得的錯誤消息更有幫助。

最後,我發現我越來越EXC_BAD_ACCESS錯誤和奇怪的行爲,因爲我幾個XIB文件前一天改名爲。我爲MainWindow.xib文件選擇了「視圖控制器」對象,並更正了NIB名稱屬性。然後,一切順利。

相關問題