更改 navigationItem 的 barButtonItem
我有一个 UIViewController。我使用 navigationItem 的 rightBarButtonItem 作为“重新加载按钮”。当按下重新加载按钮时,我使用 leftBarButtonItem 在应用程序处理数据以重新加载时显示活动指示器。到这里一切都很好。
这是一些代码:
- (void)initSpinner {
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityButton = [[UIBarButtonItem alloc] initWithCustomView: activityIndicator];
self.navigationItem.leftBarButtonItem = activityButton;
}
- (void)spinBegin {
[activityIndicator startAnimating];
}
- (void)spinEnd {
[activityIndicator stopAnimating];
}
- (void)viewDidLoad {
[self initSpinner];
[super viewDidLoad];
//more stuff going on here....
}
-(void) loadView{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshFeeds:)];
}
现在我被要求稍微改变一下逻辑。
rightBarButtonItem 保持原样。 leftBarButtonItem 仍然在那里显示活动指示器,但是当没有处理时,它应该显示另一个按钮,按下时将显示一个新视图(用于某些信息)。
所以我做了这些更改:
- (void)initSpinner {
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityButton = [[UIBarButtonItem alloc] initWithCustomView: activityIndicator];
}
- (void)spinBegin {
self.navigationItem.leftBarButtonItem = activityButton;
[activityIndicator startAnimating];
}
- (void)spinEnd {
[activityIndicator stopAnimating];
self.navigationItem.leftBarButtonItem =infoBarButton; //= [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshFeeds:)] autorelease];
}
-(void) loadView{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshFeeds:)];
if (infoBarButton == nil){
UIImage *buttonImage = [UIImage imageNamed:@"info.png"];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame = CGRectMake(0.0, 0.0, 25, 25);
// Initialize the UIBarButtonItem
infoBarButton = [[UIBarButtonItem alloc] initWithCustomView:aButton];
// Set the Target and Action for aButton
[aButton addTarget:self action:@selector(showInfo:) forControlEvents:UIControlEventTouchUpInside];
}
self.navigationItem.leftBarButtonItem = infoBarButton;
}
虽然它似乎正在工作(信息按钮在那里,当我按“重新加载”时,activityIndicator 会取代它的位置,直到处理完成),我在调试器控制台中得到以下内容:
__NSAutoreleaseNoPool(): Object 0x15ef30 of class UINavigationItem autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1abd90 of class UIBarButtonItem autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1acb20 of class UIButton autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x15ef30 of class UINavigationItem autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1ad030 of class UIActivityIndicatorView autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1ad030 of class UIActivityIndicatorView autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1a8c40 of class UINavigationButton autoreleased with no pool in place - just leaking
Object 0x941c of class NSCFString autoreleased with no pool in place - just leaking
//MORE similar messages following...
我做错了什么?我希望有人可以帮助...
提前致谢。
I have a UIViewController. I use the the rightBarButtonItem of the navigationItem as a "reload button". When the reload button is press, i use the leftBarButtonItem to display an Activity Indicator while the app is processing data to reload. Everything is ok up to here.
Here is some code:
- (void)initSpinner {
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityButton = [[UIBarButtonItem alloc] initWithCustomView: activityIndicator];
self.navigationItem.leftBarButtonItem = activityButton;
}
- (void)spinBegin {
[activityIndicator startAnimating];
}
- (void)spinEnd {
[activityIndicator stopAnimating];
}
- (void)viewDidLoad {
[self initSpinner];
[super viewDidLoad];
//more stuff going on here....
}
-(void) loadView{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshFeeds:)];
}
Now i was asked to change the logic a bit.
The rightBarButtonItem stays as is. The leftBarButtonItem is still there to display the activity Indicator, but when there is no processing it should display another button which will display a new view (for some info) when pressed.
So i did these changes:
- (void)initSpinner {
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityButton = [[UIBarButtonItem alloc] initWithCustomView: activityIndicator];
}
- (void)spinBegin {
self.navigationItem.leftBarButtonItem = activityButton;
[activityIndicator startAnimating];
}
- (void)spinEnd {
[activityIndicator stopAnimating];
self.navigationItem.leftBarButtonItem =infoBarButton; //= [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshFeeds:)] autorelease];
}
-(void) loadView{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshFeeds:)];
if (infoBarButton == nil){
UIImage *buttonImage = [UIImage imageNamed:@"info.png"];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setImage:buttonImage forState:UIControlStateNormal];
aButton.frame = CGRectMake(0.0, 0.0, 25, 25);
// Initialize the UIBarButtonItem
infoBarButton = [[UIBarButtonItem alloc] initWithCustomView:aButton];
// Set the Target and Action for aButton
[aButton addTarget:self action:@selector(showInfo:) forControlEvents:UIControlEventTouchUpInside];
}
self.navigationItem.leftBarButtonItem = infoBarButton;
}
Although it seems to be working (info button is there and when i press "reload" the activityIndicator takes its place till processing is done), i get the following in the debugger console:
__NSAutoreleaseNoPool(): Object 0x15ef30 of class UINavigationItem autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1abd90 of class UIBarButtonItem autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1acb20 of class UIButton autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x15ef30 of class UINavigationItem autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1ad030 of class UIActivityIndicatorView autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1ad030 of class UIActivityIndicatorView autoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): Object 0x1a8c40 of class UINavigationButton autoreleased with no pool in place - just leaking
Object 0x941c of class NSCFString autoreleased with no pool in place - just leaking
//MORE similar messages following...
What am i doing wrong? I hope someone out there can help...
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的猜测是,您正在后台线程中运行“重新加载”任务,当它完成时,您可以从后台线程调用
spinEnd
。如果后台线程没有自动释放池,您将看到这些警告。由于您应该只从主线程调用
UIKit
方法,因此您应该通过执行以下操作来调用spinEnd
:My guess is that you're running the "reload" task in a background thread, and when it completes you call
spinEnd
from the background thread. If the background thread doesn't have an autorelease pool in place, you will see those warnings.Since you should only ever call
UIKit
methods from the main thread, you should callspinEnd
by doing:您的属性是否被
保留
?您正在执行alloc] init...
,但在将它们分配给您的属性后并没有释放它们。我建议查看内存管理指南Are your properties being
retain
ed? You are doing andalloc] init...
but aren't releasing them after assigning them to your properties. I'd suggest checking out the Memory Management Guide