简体   繁体   English

Static UIView 添加到 superview 后变为 nil

[英]Static UIView becomes nil after added to superview

I have a static view that is used to display as a loading indicator in the UI.我有一个 static 视图,用于在 UI 中显示为加载指示器。

static UIView *loadingView;

in my class Loading.m I add loadingView into my container when show() is called在我的 class Loading.m中,当调用show()时,我将loadingView添加到我的容器中

+ (void)show {
    if (loadingView == nil) {
        UIWindow *containerView = UIApplication.sharedApplication.keyWindow;
        
        loadingView = [UIView alloc] init];
        [containerView addSubview:loadingView];
    }
}

and when dismiss() is called I remove it from superview:当调用dismiss()时,我将其从superview中删除:

+ (void)dismiss {
    if (loadingView != nil) {
        [loadingView removeFromSuperview];
        loadingView = nil;
    }
}

I found loadingView will always be nil after being added into containerView , so I will keep adding more loadingView into my containerView and it will not be removed when dismiss() is called.我发现loadingView在添加到containerView后总是 nil ,所以我会继续在我的containerView添加更多loadingView并且在调用dismiss()时它不会被删除。 When I print UIApplication.sharedApplication.keyWindow it shows an UIView has been added into the stack.当我打印UIApplication.sharedApplication.keyWindow时,它显示 UIView 已添加到堆栈中。 It seems like loadingView has lost its reference into containerView after show() is completed.show()完成后, loadingView似乎失去了对containerView的引用。

What gives?是什么赋予了?

Indeed, this question can have deeper consequences:事实上,这个问题可能会产生更深层次的后果:

  • You use static UIView .您使用 static UIView If your application is under ARC, system automatically decides if objects can live when they are not visible.如果您的应用程序在 ARC 下,系统会自动决定对象在不可见时是否可以存活。 So, you should think twice before using static declaration for visible objects.因此,在对可见对象使用static声明之前,您应该三思而后行。
  • If your object does respond to messages like removeFromSuperview and .superview is not nil - it means that the object is not nil for sure.如果您的 object 确实响应诸如removeFromSuperview.superview类的消息不nil - 这意味着 object 肯定不是nil As said above, it is bug of debugger (happens when running the app on device under XCode).如上所述,这是调试器的错误(在 XCode 下的设备上运行应用程序时发生)。

The goal of this post - to pay attention to the UIView objects ierarchy, where parent object has .subviews non-null NSArray property, indicating all objects, added as subviews.这篇文章的目标 - 注意UIView对象层次结构,其中父 object 具有.subviews非空 NSArray 属性,表示所有对象,作为子视图添加。 They will be autoreleased by ARC next to removed from the stack VC.它们将由 ARC 自动释放,然后从堆栈 VC 中删除。 So, in case of static UIView * declaration, ARC will keep loaded all its parent elements until it will be manually removed from superview.因此,在static UIView *声明的情况下,ARC 将继续加载其所有父元素,直到将其手动从 superview 中删除。 In other words, static UIView * is potentially dangerous construction and can lead to memory leaks or other conflicts.换句话说, static UIView *是潜在的危险结构,可能导致 memory 泄漏或其他冲突。 Better way to control loading indicator, for instance - is to check last subview element of current top VC:例如,控制加载指示器的更好方法是检查当前顶级 VC 的最后一个子视图元素:

if (self.view.subviews && [self.view.subviews.lastObject isKindOfClass: [loadview class]]) {
    [self.view.subviews.lastObject removeFromSuperview];
}

In this case you have no risk to of calling nil object methods (app crashes as well) and headache of manual lifecycle control.在这种情况下,您无需担心调用nil object 方法(应用程序也会崩溃)和手动生命周期控制的麻烦。

How you detected that's "loadingView" is nil?您如何检测到“loadingView”为零?

Please verify it via code or using "po" in Debugger.请通过代码或在调试器中使用“po”进行验证。

If you just saw "nil" value in variables list, sometimes it's Xcode debugger bug.如果您刚刚在变量列表中看到“nil”值,有时它是 Xcode 调试器错误。 When variable "nil" in variable list, but it's not "nil".当变量列表中的变量“nil”,但它不是“nil”时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM