0

我有一個UINavigationController,當用戶在頁面中循環時(通常是相同的順序),我們會將三個視圖推送到它上面 - 我將它們視爲view0,1和2,以便與導航控制器的標記對齊。視圖在Storyboard中創建。如何確保popToRootViewControllerAnimated的工作原理?

當視圖的進度完成,並且用戶想要返回到開始時,我使用popToRootViewControllerAnimated:YES來響應按鈕推送,並且UI適當地返回到view0。但是,如果我再次遍歷整個循環,我偶爾會得到「幻影」日誌語句來響應應用程序範圍的通知,從而明確view1(中間視圖)從未完全釋放。我在xcode 4.2.1中僅使用了ARC,並且僅使用了iOS5 +代碼,所以ARC應該很好地處理事情。

我見過幾篇文章,提示ARC不會釋放其引用計數未降至0的視圖,所以我已盡我所能將屬性設置爲零,顯示當我推到最後的視圖時沒有任何東西被留下...並且NavigationController之外沒有任何東西引用view1(我知道的)。剖析殭屍程序和內存泄漏的應用程序不會產生任何結果。

如何查看/記錄/調試仍然可能引用該視圖的內容?我怎麼能告訴它已經成功dealloc'ed沒有把它會阻止dealloc的東西?

我的代碼如下(基本上):

view0推動使用故事板「推」到賽格瑞VIEW1。

視圖1:

- (void)viewDidLoad 
    { 
    [super viewDidLoad]; 

    /* register as observer for some notifications */ 
    /* set properties and format an image or two */ 
    } 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

/* start some animation here */ 
} 


- (void) receiveNotification { 

NSObject *newObject = [[NSObject alloc] init]; 

[newObject doStuff]; 

/* Remove notification observers */ 

} 


- (void)objectDelegateMethod:(NSDictionary *) dataReturned { 

/* do stuff with dataReturned */ 
self.propertyName = dataReturned; 

[self performSegueWithIdentifier:@"AllDone" sender:self]; 

} 


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 

if ([[segue identifier] isEqualToString:@"AllDone"]) 
{ 

View2ViewController *destinationView = [segue destinationViewController]; 

destinationView.propertyMagic = self.propertyName; 

[self setPropertyName:nil]; 
//do same with all other properties 

} 

視圖2:

- (void)viewDidLoad 
{ 

/* display things based on self.propertyMagic */ 

} 


- (IBAction)userStartsOverButton:(id)sender { 

[self.navigationController popToRootViewControllerAnimated:YES]; 

} 

鑑於上述(粗糙)的結構,如果我不刪除廠景作爲通知的觀察員,它繼續響應和輸出即使我不明白爲什麼它沒有被釋放。即使當我移除觀察者時,隨着我在應用程序運行中循環並最終導致事件崩潰(儀器中沒有檢測到泄漏),內存使用情況繼續增加。

我該如何解決這個問題?

回答

1

如果你運行過泄漏和殭屍,那麼......你可能沒有任何泄漏或過度釋放。

「看到」 ARC下dealloc的發生,你可以添加一個空記錄dealloc到類:

 
- (void)dealloc 
{ 
    NSLog(@"%s:%d", __func__, __LINE__); 
} 
+0

這是一個非常有用的建議,從未在非ARC環境中編程的Obj-C的人,非常感謝!事實證明,如果我在運行popToRootViewControllerAnimated之前從view1中刪除所有子視圖,則ARC會解除該視圖的分配。然而,奇怪的部分是,dealloc通常會延遲幾分鐘......這是ARC期望的嗎?在java中,我知道你可以調整垃圾收集頻率等,但我認爲ARC比這個稍微乾淨一些。 – Amos 2012-03-23 15:39:36

+0

另外,可能值得注意的是,在應用程序的其他任何地方都沒有對view1的自寫引用。它通過一個鍋爐板Storybard segue來實例化,並通過類似的,但自定義的繼續來顯示關閉view2的職責。 – Amos 2012-03-23 15:52:10

+0

...我剛剛意識到我的垃圾回收評論是如何誤導了閱讀後:http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1 我想一些東西仍然持續觀看1短時間,否則會立即釋放,不是嗎?故事板是否仍然可以引用它? – Amos 2012-03-23 16:16:40

0

你可以檢查的一件事是,如果任何其他對象有指向view1的(strong)指針。如果是這樣,您可能需要將其更改爲(weak)或者只是不參考它。 (在view0和view1之間以及view1和view2之間尋找一個可能的保留週期,也許它們保持彼此的引用)。

如果ARC不再由任何其他對象所有,它將在對象上釋放。所以,你也可以嘗試覆蓋到-popToRootViewControllerAnimated:方法上view0並調用是這樣的:

self.view1 = nil; 

如果view0是保持一個參考VIEW1的唯一對象,廠景應該被釋放(dealloced)。

+0

嘿,如果我知道發生了什麼仍然引用它,我將與nilling出來玩和/或嘗試像弱與強的東西;) – Amos 2012-03-23 15:33:47