欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS使用[UIApplication sharedApplication].keyWindow添加子视图的问题

程序员文章站 2022-06-30 23:42:39
开发的时候我们经常遇到这样的场景,就是在当前视图界面上添加一个黑色透明的蒙版。一般我们就是新建一个蒙版view,然后加在当前显示的window上。如下: 1-1代码 uiwindow *wind...

开发的时候我们经常遇到这样的场景,就是在当前视图界面上添加一个黑色透明的蒙版。一般我们就是新建一个蒙版view,然后加在当前显示的window上。如下:

1-1代码

uiwindow *window = [uiapplication sharedapplication].keywindow;//注:keywindow当前显示界面的window
    uiview *subview = [[cview alloc] initwithframe:[uiscreen mainscreen].bounds];
    subview.backgroundcolor = [uicolor blackcolor];
    subview.alpha = 0.5;
    [window addsubview:subview];

一般我们就是在keywindow上直接添加这种蒙版的view,小编也不例外。但今天确遇到了一个诡异的问题,就是由于使用这个keywindow造成的。

下面简单交代下问题背景:

项目中有这样的场景,就是点击某一按钮之后,会优先弹出一个的uialertview的弹框,然后会在alertview的点击代理的回调

- (void)alertview:(uialertview *)alertview clickedbuttonatindex:(nsinteger)buttonindex

里面调用显示蒙版的方法(方法的实现和上面1-1代码类似)。然后就出现了奇怪的问题,我添加在keywindow上的蒙版加上去之后瞬间消失了。

分析问题:

1.看到蒙版自己消失了第一反应想到应该会走自定义蒙版view的dealloc方法,于是就在dealloc方法那打了一个断点。

2.果然走到我们的蒙版view dealloc方法被调用了,但我又没有自己掉dimiss和remvoe方法,怎么会dealloc的。

3.分析调用dealloc之前的方法栈,

iOS使用[UIApplication sharedApplication].keyWindow添加子视图的问题

发现window调用了dealloc,因为我们蒙版的父视图keywindow dealloc释放掉了,所以我们的蒙版就消失了

4.解释了蒙版的消失,但当前的window怎么dealloc呢?我的界面明明还正常显示呢。

5.猜测是不能当前显示蒙版的keywindow和我们显示主界面的keywindow不一样导致的,但为啥会不一致呢,之前这样把蒙版直接加在keywindow上都没关系,难道和在alertview回调显示有关系。

6.做了上面大胆的假设,开始一步步调试,

//a.在alertveiw弹框弹出之前打印keywindow的值
(lldb) po [uiapplication sharedapplication].keywindow
; layer = >
//b.在alertview的代理方法- (void)alertview:(uialertview *)alertview clickedbuttonatindex:(nsinteger)buttonindex里打印keywindow的值

po [uiapplication sharedapplication].keywindow
<_uialertcontrollershimpresenterwindow: 0x7fa48c613ad0; frame = (0 0; 414 736); opaque = no; autoresize = w+h; gesturerecog
//c.在alertview的代理方法- (void)alertview:(uialertview *)alertview diddismisswithbuttonindex:(nsinteger)buttonindex alertview消失之后再打印
(lldb) po [uiapplication sharedapplication].keywindow
; layer = >
通过上面的打印,我们可以清楚的看到。在alertview弹出之后的keywindow和我们弹出之前消失之后的keywindow是不一样的。地址和对象都不同一个
uiwindow: 0x7fa48c611c00 和 _uialertcontrollershimpresenterwindow: 0x7fa48c613ad0

这就解释了为啥我们弹出的视图出现后就消失了,因为当alertveiw弹出的时候的当前的keywidow已经是_uialertcontrollershimpresenterwindow对象了,alertview消失之后,这个window就释放了,所以加在上面的蒙版就消失了。

解决方法:

1.我们看到在uialertview另一个回调里- (void)alertview:(uialertview *)alertview diddismisswithbuttonindex:(nsinteger)buttonindex uialertview dismiss之后的keywindow和我们是一样的,可以在这里使用[uiapplication sharedapplication].keywindow方式去加视图。

2.不适用[uiapplication sharedapplication].keywindow这种方式,[[uiapplication sharedapplication] delegate].window 或

[[uiapplication sharedapplication].windows objectatindex:0]这两种方式,这样获取的window不是当前的keywindow,而是主window。

总结分析:

1.使用uialertview的时候,无论是自己写还是封装给别人使用的时候,最好都

- (void)alertview:(uialertview *)alertview diddismisswithbuttonindex:(nsinteger)buttonindex 这个回调,因为这是alertview已经完全消失。

2.我们不可避免的会遇到问题,我们平常习以为常的东西,有些场景也会遇到一些特殊的问题,我们要保持警惕。

3.遇到问题,才能更好的提升,多做总结。