[英]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:事实上,这个问题可能会产生更深层次的后果:
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
声明之前,您应该三思而后行。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.