我仍然专注于指针。我写了下面的代码,并对我的好处表示怀疑。
我需要我的视图控制器才能为它的UIBarButtonItem设置自定义标题,具体取决于它将推送到导航控制器堆栈的新视图控制器。在我尝试设置它的新标题之前,每次都检查self.navigationItem.backBarButtonItem是否存在条件代码(因为默认情况下,除非你创建它,self.navigationItem.backBarButtonItem是nil),我做了这个:
它有效,但任何人都可以指出为什么我不应该这样做: 我有一个自定义的getter懒惰实例化导航栏后退按钮:
- (UIBarButtonItem *)myBackButton {
if (!myBackButton) {
myBackButton = [[[UIBarButtonItem alloc] initWithTitle:self.title style:UIBarButtonItemStylePlain target:nil action:nil] retain];
self.navigationItem.backBarButtonItem = myBackButton;
}
return myBackButton;
}
现在在.m文件的其余部分,每当我想要更改后退按钮的标题时(例如,在我将新视图控制器推到导航控制器的堆栈之前),我只是这样做:
self.myBackButton.title = @"Some Custom Title";
或:
self.myBackButton.title = self.title;
我相信这是有效的,因为self.myBackButton和self.navigationItem.backBarButtonItem指向同一个对象。这种对象的间接设置是否可取?如果没有,那么处理条形按钮场景的更好方法是什么?
非常感谢, 马特
答案 0 :(得分:2)
您应该阅读“内存管理指南”以了解alloc,retain,...
你正在分配后退按钮(=你拥有它)并且你也保留它(=你拥有它两次),因此你也必须两次调用释放。
不需要懒惰地实例化后退按钮,这是一小块内存,我认为你总是希望它可见。更好的方法是在UIViewController的init方法中执行此操作。
正确的方法是......
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:self.title style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
...总结内存管理指南规则......
答案 1 :(得分:1)
您可能希望将该方法更改为此类。
- (UIBarButtonItem *)myBackButton {
if (!myBackButton) {
myBackButton = [[[UIBarButtonItem alloc] initWithTitle:self.title style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
}
return myBackButton;
}
然后,在其他地方(可能在你的viewDidLoad /中出现)调用
self.navigationItem.backBarButtonItem= self.myBackButton;
我已将retain更改为autorelease,因为任何使用init,copy或new的方法都会导致保留计数。如果它不包含init copy或new,它应该返回一个自动释放的实例。
当你将它设置为backbuttonItem时,无论如何都会保留它。
值得注意的是,当通过点表示法访问属性时,您实际上是通过setter和getters。即
self.myBackButton.title =@"title";
与
相同[[self myBackButton] setTitle:@"title"];
你应该几乎总是通过setter和getter而不是作为局部变量访问它。即使用
self.myBackButton而不是myBackButton,因为这将允许您在通过时进行任何所需的设置,并且还知道如果任何代码正在访问它,它将通过该方法而不是直接更改变量。 / p>
答案 2 :(得分:0)
是的,你不清楚内存管理规则,但更多的是你的问题:不,不要打扰实现这个后退按钮访问器,已经有一个后退按钮访问器,它是self.navigationItem.backBarButtonItem
。
您建议使用的这种方法是一个惰性访问器,当您在调用访问器之前拥有一个不需要的对象时,可以使用它。它将对象创建的细节隐藏给不需要知道的调用者。
然而,在这种情况下,导航视图控制器在正确的时间需要对象,按钮,并且应该在有意义的地方创建。这是在视图控制器中,我认为应该在init,loadView或viewWillAppear中创建按钮。在这种情况下,按钮创建的详细信息应该显示在您拥有它的任何一个位置。
所以取出那个访问者,无论你想在哪里使用self.myBackButton.title
而不是self.navigationItem.backBarButtonItem
,最后确保在你必须访问它之前在一个被调用的地方初始化它(通常是你的init)
答案 3 :(得分:-3)
您的问题归结为:按下后退按钮会发生什么 - 当它控制的视图被释放时。在这些情况下检查后退按钮的保留计数。如果它保持稳定,你就可以了(假设你的程序中没有其他模块分配不同的后退按钮实例)。否则,每次需要时都需要创建一个新的后退按钮。