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