2

我在我的 iPhone 应用程序的导航栏中添加了一个刷新 UIBarButtonItem。当用户点击按钮时,我希望刷新按钮更改为动画活动指示器,并且一旦操作(在本例中为下载)完成,将活动指示器切换回刷新按钮。

我已经使用 IB 添加了刷新按钮。然后在按钮上点击我创建一个新的活动指示器并保持指向原始刷新按钮的指针。像这样:

refreshButtonItem = self.navigationItem.leftBarButtonItem;
if (activityButtonItem == nil)
{
    activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20,20)];
    activityButtonItem = [[UIBarButtonItem alloc]initWithCustomView:activityIndicator];

}
self.navigationItem.leftBarButtonItem = activityButtonItem;
[activityIndicator startAnimating];

到目前为止,一切都很好。问题是当我的下载完成并尝试重新添加刷新按钮(使用以下):

[activityIndicator stopAnimating];
self.navigationItem.leftBarButtonItem = refreshButtonItem;

我收到以下错误:
[UIBarButtonItem retain]: message sent to deallocated instance

我没有明确地调用释放。

A) 何时/何地解除分配

B)有没有更好的方法来实现我正在寻找的东西?

4

2 回答 2

1

当您将activityButtonItem 分配给leftBarButtonItem 时,leftBarButtonItem 曾经指向的项目被释放。leftBarButtonItem(以及所有带有 retain 选项的属性)的实现方式与此类似:

- (void)leftBarButtonItem:(UIBarButtonItem *)newItem {
  if (newItem != self.leftBarButtonItem) {
    [self.leftBarButtonItem release];
    leftBarButtonItem = [newItem retain];
  }
}

如果要在重新分配 leftBarButtonItem 后使用 refreshButtonItem,请将第一行更改为:

refreshButtonItem = [self.navigationItem.leftBarButtonItem retain];

于 2010-02-12T03:23:53.950 回答
0

由于 iOS 5 引入了 ARC,您不再需要保留。

可以像@cagreen 解释的那样获得解决方案,而 refreshButtonItem 可以存储为类属性,以及 loadingButton 和 loadingView。

在您的界面中声明:

@property (strong, nonatomic) UIBarButtonItem *refreshButton;
@property (strong, nonatomic) UIBarButtonItem *loadingButton;
@property (strong, nonatomic) UIActivityIndicatorView *loadingView;

在 viewDidLoad 方法中初始化 loadingButton 和 loadingView:

self.loadingView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
self.loadingButton = [[UIBarButtonItem alloc] initWithCustomView:self.loadingView];

然后要显示加载微调器,您可以简单地执行以下操作:

 // Shows loading button
- (void)showLoadingView {

    // Keep reference to right bar button
    if (self.navigationItem.rightBarButtonItem) {
        self.refreshButton = self.navigationItem.rightBarButtonItem;
    }

    // Start animating and assign loading button to right bar button
    [self.loadingView startAnimating];
    self.navigationItem.rightBarButtonItem = self.loadingButton;
}

并隐藏:

 // Hides loading button
- (void)hideLoadingView {
    [self.loadingView stopAnimating];
    self.navigationItem.rightBarButtonItem = self.refreshButton;
}
于 2017-01-20T10:53:45.943 回答