0

據我瞭解SDK文檔UIViewController的navigationItem生命週期綁定到控制器本身,而不是控制器的視圖。即在默認實現中,它是按需創建的並且被視圖控制器銷燬 - 所有內容都像按鈕項目和titleView。鑑於按鈕項和titleView可能由UIView實例表示 - 這是否意味着一旦創建這些視圖將留在內存中,直到控制器被銷燬並通過所有內存警告生存下來?UINavigationItem生命週期

這個設計決定背後的意義是什麼?對內存使用的影響是否被認爲太小而不能打擾?對於使用自定義導航欄按鈕/標題的應用程序,它真的很小嗎?

很容易明確地將一些navigationItem屬性綁定到控制器的視圖生命週期 - 就像在-viewDidLoad中設置titleView並將其放入-viewDidUnload(self.navigationItem.titleView = nil)中一樣。但navigationItem屬性文檔suggests to avoid this pattern。除了使用後退按鈕的示例以外是否還有其他潛在問題?

回答

0

添加了一個類別(snippet2)來跟蹤保留計數和導航項目的銷燬,可以自由地做同樣的事情:)似乎它不會釋放內存警告。一個常見的解釋是視圖控制器不必與導航控制器一起使用:這應該是爲什麼nav-item添加了一個單獨的類別(snippet1),並且它的生命週期必須使用nav-控制器,而不是視圖控制器實例本身。

在這種情況下,自定義導航項目太重,以致於需要儘可能釋放它, 我會離開默認實現,添加自定義導航項目類別並手動管理這些項目(我希望通過重寫需要UINavigationController方法,如導航控制器didReceiveMemoryWarningpushViewController:animated:,popViewControllerAnimated:animated:)。然而,當我真的需要這樣的情況時,我無法想象。

片斷1

@interface UIViewController (UINavigationControllerItem) 

@property(nonatomic,readonly,retain) UINavigationItem *navigationItem; // Created on-demand so that a view controller may customize its navigation appearance. 
@property(nonatomic) BOOL hidesBottomBarWhenPushed; // If YES, then when this view controller is pushed into a controller hierarchy with a bottom bar (like a tab bar), the bottom bar will slide out. Default is NO. 
@property(nonatomic,readonly,retain) UINavigationController *navigationController; // If this view controller has been pushed onto a navigation controller, return it. 

@end 

片斷2

@implementation UINavigationItem (Logs) 


- (id)init 
{ 
    NSLog(@"I'm initialized (%@)", [self description]); 
    self = [super init]; 
    return self; 
} 

-(void) release 
{ 
    NSLog(@"I'm released [%d](%@)", [self retainCount], [self description]); 
    [super release]; 
} 

-(void) dealloc 
{ 
    NSLog(@"I'm deallocated [%d](%@)", [self retainCount], [self description]); 
    [super dealloc]; 
} 

@end 
+0

跟蹤保留計數是無用的。跟蹤dealloc。 – bbum

+0

@bbum我對一個大的版本調用計數印象深刻,不確定別人覺得它有趣,但無論如何。由於日誌被放置在[超級版本]之前,所以使用retainCount 1釋放調用應該沒問題。我不知道dealloc是否必須在發佈後立即被調用,但這對我來說非常接近dealloc。 –

+1

我想你誤會了;從'retainCount'返回的結果無論在這種情況下還是在一般情況下都是沒有意義的,並且'release'的覆蓋並不顯示任何特別有趣的內容。雖然您可以在那裏設置斷點,但使用分配工具追蹤所有保留/釋放事件要好得多。 – bbum