You need to enable JavaScript to run this app. 静态UIView添加到父视图后变为nil 调用dismiss无法移除重复新增实例
优惠活动
大模型
产品
解决方案
定价
更多

静态UIView添加到父视图后变为nil 调用dismiss无法移除重复新增实例

问题原因及修复方案

核心原因

以下是导致该问题的几种常见场景,按出现概率从高到低排列:

  • 静态变量定义位置错误
    static关键字的作用是限定变量作用域仅属于当前编译单元,如果你将static UIView *loadingView;定义在Loading.h头文件中,每一个引入了Loading.h的.m文件都会生成独立的loadingView副本。你在Loading.m的show方法中赋值的是当前编译单元的副本,其他操作如果访问到其他副本就会出现值为nil的情况,导致重复创建视图、dismiss无法匹配对应实例。
  • MRC编译环境下未手动持有对象
    如果项目未开启ARC,static UIView *loadingView默认为assign类型,不会持有对象。你创建的视图实例在自动释放池清空后会被释放,静态变量变为野指针,系统判定为nil,导致后续操作无法匹配已有实例。
  • 非主线程执行UI操作
    UIKit所有操作必须在主线程执行,如果你在子线程调用show或dismiss方法,会导致赋值、视图添加/移除操作未正确执行,出现变量状态异常。
  • 代码语法错误或编译缓存异常
    你提供的show方法中创建视图的代码存在语法错误:loadingView = [UIView alloc] init];缺少左括号,正确写法应为loadingView = [[UIView alloc] init];。如果实际代码存在该错误,或Xcode存在旧编译缓存,会导致赋值操作未正确执行。

修复方案

  1. 将静态变量移至Loading.m文件顶部,不要放在头文件中:
// Loading.m 顶部定义,不要写入Loading.h
static UIView *loadingView;

@implementation Loading
// 类方法实现写在这里
@end
  1. 确保UI操作都在主线程执行,优化show和dismiss方法实现:
+ (void)show {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (loadingView == nil) {
            UIWindow *containerView = UIApplication.sharedApplication.keyWindow;
            NSParameterAssert(containerView);
            // 修正语法错误
            loadingView = [[UIView alloc] init];
            // 补充必要的布局配置,否则视图默认大小为0
            loadingView.frame = containerView.bounds;
            loadingView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
            [containerView addSubview:loadingView];
        }
    });
}

+ (void)dismiss {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (loadingView != nil) {
            [loadingView removeFromSuperview];
            loadingView = nil;
        }
    });
}
  1. 如果项目使用MRC编译,给静态变量赋值时添加retain操作:
// MRC环境下的赋值写法
loadingView = [[[UIView alloc] init] retain];
  1. 清理Xcode编译缓存(快捷键Shift + Cmd + K)后重新编译运行,排除缓存导致的异常。

内容的提问来源于stack exchange,提问作者Chan Tak Zee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 06:45:03