当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS使用[UIApplication sharedApplication].keyWindow添加子视图的问题

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

2018年10月03日  | 移动技术网移动技术  | 我要评论

开发的时候我们经常遇到这样的场景,就是在当前视图界面上添加一个黑色透明的蒙版。一般我们就是新建一个蒙版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之前的方法栈,

\

发现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.遇到问题,才能更好的提升,多做总结。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网