关闭视图时 performSelectorInBackground 导致随机崩溃

Posted

技术标签:

【中文标题】关闭视图时 performSelectorInBackground 导致随机崩溃【英文标题】:performSelectorInBackground causes random crash when view is dismissing 【发布时间】:2012-10-03 19:05:33 【问题描述】:

我的这部分代码发生了一些随机崩溃:

-(void) goBack 

        [self performSelectorInBackground:@selector(addActivityIndicator) withObject:nil];

        [self.navigationController popViewControllerAnimated:YES];

        

- (void)addActivityIndicator 
        @autoreleasepool 

            UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

            UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityView];

            [activityView startAnimating];

            self.navigationItem.leftBarButtonItem = barButton;

        
    

当我想退出这些方法所在的屏幕时,另一个 ViewController 必须处理一些数据。为了通知用户正在进行处理,我在导航栏的左侧按钮中添加了一个活动指示器。

问题是有时我在addActivityIndicator 方法中得到一个exc_bad_access。频率非常随机,XCode有时会在@autoreleasepool的末尾显示错误,有时在self.navigationItem.leftBarButtonItem = barButton;的行

我想有时我的 viewController 被破坏但线程仍在运行并尝试访问不再存在的对象的 navigationItem。但我不确定这是否是问题所在,也不知道如何解决。

我在我的项目中使用 ARC,这个问题出现在我测试的所有 ios 版本中。

请,任何人都可以解释一下发生了什么,我该如何解决这个问题?

谢谢。

【问题讨论】:

我不明白你为什么要这样做。修改要从导航堆栈中删除的视图的导航项有什么意义? 因为出现的视图必须处理一些繁重的东西,而我当前的视图在处理完成之前不会消失。也许有更好的方法来表明...... 【参考方案1】:

你不应该在后台做 UIKit 的事情。

【讨论】:

感谢您的回答。但是,如果我将“addActivityIndi​​cator”代码放入我的 goBack 函数中,则 UI 会保持冻结状态,并且 ActivityIndi​​cador 仅在视图消失时出现。这样做的正确方法是什么?【参考方案2】:

通过调用[self performSelectorInBackground:@selector(addActivityIndicator) withObject:nil];,您正在后台线程上更新 UI。您应该只在主线程上更新 UI。

编辑

根据您的评论,您正在尝试在视图弹出之前更新 UI。这样做的方法是:

[self addActivityIndicator]

[navigationController performSelector:@selector(popViewControllerAnimated:) withObject:[NSNumber numberWithBool:YES] afterDelay:0];

您也可以查看dispatch_after

【讨论】:

感谢您的回答。但是,如果我将“addActivityIndi​​cator”代码放入我的 goBack 函数中,则 UI 会保持冻结状态,并且 ActivityIndi​​cador 仅在视图消失时出现。这样做的正确方法是什么? 也许在viewDidLoad 中添加活动指示器,但将其设置为隐藏(隐藏为YES)。当你想显示活动指示器时,将隐藏设置为NO

以上是关于关闭视图时 performSelectorInBackground 导致随机崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何在关闭视图控制器时获得淡出动画

在关闭作为模型视图本身的视图 1 时呈现视图(全屏)控制器

关闭模式视图时未调用 onDisappear

在应用程序退出时关闭模式视图控制器

当用户点击视图外的任意位置时关闭视图

关闭当前视图控制器时 UIView 框架发生变化