设置 rightBarButtonItem 禁止 UIViewController 被释放

Posted

技术标签:

【中文标题】设置 rightBarButtonItem 禁止 UIViewController 被释放【英文标题】:Setting rightBarButtonItem prohibiting UIViewController from being deallocated 【发布时间】:2014-03-05 02:19:49 【问题描述】:

我整天都在调试为什么我的UIViewController 在被解雇后没有被释放,我已经将其范围缩小到我正在设置一个 rightBarButtonItem 的事实。我的项目正在使用 ARC。

在我的appDelegate 中,如果用户尚未登录,我会显示一个“欢迎”屏幕:

// AppDelegate.m
WelcomeViewController *welcome = [[WelcomeViewController alloc] initWithContext:AuthenticationPresentationContextSplash];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:welcome];
[self.window.rootViewController presentViewController:nav animated:false completion:nil];

然后,当用户登录或点击 rightBarButtonItem 时,我关闭 viewController:

// WelcomeViewController.m
- (IBAction)onSkipOrCancel

    [self.presentingViewController dismissViewControllerAnimated:true completion:nil];

我已经确认在AppDelegateWelcomeViewController 中,self.window.rootViewController 和 self.presentingViewController 指的是同一个 UIViewController 的完全相同的实例。

奇怪的是,经过一整天的工作,我发现问题出在这段代码中:

// also in WelcomeViewController.m
- (void)configureRightBarButtonItem

    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithTitle:@"Skip"
                                                                  style:UIBarButtonItemStylePlain
                                                                 target:self
                                                                 action:@selector(onSkipOrCancel)];

    // if i comment this out, when onSkipOrCancel runs and the presentingViewController
    // is sent dismissViewController, WelcomeViewController will successfully get deallocated
    self.navigationItem.rightBarButtonItem = rightItem;

似乎在设置rightBarButtonItem 时创建了对WelcomeViewController 的强引用。为什么会这样?我该如何解决?

【问题讨论】:

您是否使用 Instruments 中的分配工具来查看持有对视图控制器的引用的内容?您可能会看到一些其他意外引用,这些引用可能是设置按钮的副作用。 您可能还想将您的 onSkipOrCancel 方法更改为:[self dismissViewControllerAnimated:YES completion:nil]; 不幸的是,将其更改为 [self dismissViewControllerAnimated] 并没有解决问题。 我还没有使用分配工具,因为我不太确定如何找到那种类型的信息(找出还有谁持有对视图控制器的引用)。你能提供一些步骤来帮助我吗? 以下内容应该有所帮助:***.com/questions/20471973/… 【参考方案1】:

试试这个

// also in WelcomeViewController.m
- (void)configureRightBarButtonItem

    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithTitle:@"Skip"
                                                                  style:UIBarButtonItemStylePlain
                                                                 target:self
                                                                 action:@selector(onSkipOrCancel)];

    // if i comment this out, when onSkipOrCancel runs and the presentingViewController
    // is sent dismissViewController, WelcomeViewController will successfully get deallocated
    self.navigationItem.rightBarButtonItem = rightItem;
    [rightItem release];//whenever we alloc we should release it too!

【讨论】:

我应该添加我正在使用 ARC。【参考方案2】:

经过一天的痛苦,事实证明这是 Taplytics v1.2.24 中的一个错误。该错误已在 1.2.32 中修复。

他们在 UIBarButtonItem 上有一个类别,他们在其中进行一些方法调动,并持有对 rightBarButtonItem 目标(这是我的 viewController)的强引用。这反过来又阻止了我的 UIViewController 释放。

【讨论】:

哎哟。这是一个艰难的过程。

以上是关于设置 rightBarButtonItem 禁止 UIViewController 被释放的主要内容,如果未能解决你的问题,请参考以下文章

从导航控制器设置 rightBarButtonItem

rightBarButtonItem 出现在中间

rightBarButtonItem 没有出现在导航栏 iOS

iOS关于自定义rightBarButtonItem

iOS7 iphone rightBarButtonItem 标题未正确居中/显示

rightbarbuttonitem 没有出现?