2011-11-16 71 views
1

我碰到了,當我popToRootViewController,這是我設置它的方式。關閉popover,然後popToRootViewController,EXC_BAD_ACCESS

我:

@property (nonatomic, retain) UIPopoverController *popover; 

中的dealloc:

[popover release]; 

當按鈕被按下

if (self.popover == nil) { 
    DetailViewController *detailView = [[[DetailViewController alloc] init] autorelease]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(GoToTest:) name:TestDetailPressed object:detailView]; 
    self.popover = [[[UIPopoverController alloc] initWithContentViewController:detailView] autorelease]; 
    self.popover.delegate = self; 
    [self.popover presentPopoverFromRect:frame inView:self.scrollView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
} 

DetailViewController本質上只是一個UITableView。當選擇一排,我發佈一個通知回到這個當前類GoToTest:

- (void)GoToTest:(NSNotification *)notification { 
    if ([self.popover isPopoverVisible]) { 
     [self.popover dismisspopoverAnimated:YES]; 
     [self handleDismissedPopover:self.popover]; 
    } 
    [self.navigationController popToRootViewControllerAnimated:NO]; 
} 

- (void)handleDismissedPopover:(UIPopoverController *)popoverController { 
    self.popover = nil; 
    self.popover.delegate = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TestDetailPressed object:nil]; 
} 

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 
    [self handleDismissedPopover:popoverController; 
} 

當我在儀器運行它,我得到的殭屍消息

-[UIPopoverController _popoverDismissAnimationCompleted] 

UIViewController有此時的refCt爲-1。

回答

2

你可能想改變self.popover = nillpopover = nil因爲第一(self.popover = nil)將調用屬性setter,釋放舊值並設置成員爲零。另外,將屬性nil前的代表置零。

要修復,改變這種:

- (void)handleDismissedPopover:(UIPopoverController *)popoverController { 
    self.popover = nil; 
    self.popover.delegate = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TestDetailPressed object:nil]; 
} 

要:

- (void)handleDismissedPopover:(UIPopoverController *)popoverController { 
    popover.delegate = nil; 
    popover = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TestDetailPressed object:nil]; 
} 

如果還是不行,在調試器設置NSZombieEnabledMallocStackLoggingguard malloc。然後,當你的應用程序崩潰,在gdb的控制檯輸入:

(gdb) info malloc-history 0x543216 

替換0x543216與導致崩潰的對象的地址,你會得到一個更加有用的堆棧跟蹤,它應該幫助你查明導致問題的代碼中的確切行。

See this article for more detailed instructions.

+0

我會想象popover.delegate = nil; popover後=零;是毫無意義的。 – jbat100

+0

@ jbat100它是,很好的捕獲。更新回答) – chown

+0

@chown malloc:使用標準記錄器記錄malloc堆棧到磁盤是什麼意思? –

0

而且,你顯式調用:在dealloc中

[popever release]; 

?因爲你這樣做:

self.popover = nil; 

,將釋放對象,你不必擔心它在你的dealloc。但是,就像@chown說的那樣,使用Instruments Zombie工具,它會馬上告訴你發生了什麼。