不允许在解除分配时尝试加载视图控制器的视图,这可能会导致未定义的行为

Posted

技术标签:

【中文标题】不允许在解除分配时尝试加载视图控制器的视图,这可能会导致未定义的行为【英文标题】:Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior 【发布时间】:2016-02-19 02:31:08 【问题描述】:

此警告仅出现一次。我将UIAlertView 分配在一个基础中:

viewController's viewDidLoad`self.alertView = [[UIAlertView alloc] initWithTitle.....`,

 `- (void)viewDidDisappear:(BOOL)animated 
    [super viewDidDisappear:animated];
    self.alertView = nil;
`

viewController A 和 viewController B 继承自基础 viewController。

当这个 viewController A 推送到 viewController B 时出现警告,但是 B 弹出到 A 并且 A 再次推送到 B,这个警告不会出现。

当我使用模拟器 (ios 9.2) 时,会出现警告,但当我使用 iPhone (iOS 8.2) 时,它不会出现。

【问题讨论】:

【参考方案1】:

不要在viewDidLoad中分配初始化alertView,使用时分配alertView;

【讨论】:

【参考方案2】:

不需要在 ARC 中解除分配属性。如果您有特殊需要,请在viewWillDisappear 中执行此操作。

【讨论】:

解除分配清理的最佳位置是 -(void)dealloc() 方法,该方法在对象解除分配时自动调用。当视图消失时,并不意味着它被释放。例如,视图可以在从它的 push segue 中消失,但它仍将作为对象存在。 @AlexeyLobanov 我说的是“特殊需求”,当你推送一个新的视图控制器时,dealloc 不会调用。 是的视图(不是视图,而是视图控制器和视图作为它的属性)不会在推送时被释放,因为 UI 需要一个视图在倒带时返回;)但在某些情况下,可能需要清理 ARC dealloc 和保证它的地方是 -(void)dealloc()【参考方案3】:

如果我理解正确,您在 Base 类中定义了警报,并且只需要在 A:Base 中显示它,而不需要在 B:Base 中显示它。如果是这样,这里是代码:

- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:(BOOL)animated];
    if ([self isKindOfClass[A class]]) 
        [self presentViewController:self.alert animated:YES completion:nil]; 
    

【讨论】:

此 alertView 仅用于显示错误信息。例如 A 需要显示网络错误,并且当 A 推送到 B 时我不希望 alertView 显示。如果我删除 self.alterview = nil ;警告和以前一样。 1) 通过以下方式检查当前 A 或 B 类:if ([self isKindOfClass[A class]]) 以及显示警报之前的其他错误条件或您不在 B 中if (![self isKindOfClass[B class]]) 2) 不要通过在 viewDidDisappear 中将警报分配给 nil 来删除警报

以上是关于不允许在解除分配时尝试加载视图控制器的视图,这可能会导致未定义的行为的主要内容,如果未能解决你的问题,请参考以下文章

尝试在解除分配时加载视图控制器的视图... UIAlertController

尝试在解除分配时加载视图控制器的视图。核心聚焦

UISearchController - 警告尝试加载视图控制器的视图

解除视图控制器警告

模态转换后解除分配 SKScene

解除键盘后,带有所选文本的UITextView不响应触摸