创建的UIWindow为什么不显示

创建了一个window却不显示,怎么个情况。
相关代码如下:
创建一个按钮,通过按钮的单击事件来创建window,创建的window是不需要添加到相关的控件的,只要创建就会添加到界面上。
1、但是这里也创建window了,怎么没有显示?

- (void)test2
{
    UIWindow *myWindow3 = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    myWindow3.backgroundColor = [UIColor greenColor];
    myWindow3.windowLevel = 100;
    myWindow3.hidden = NO;
    [myWindow3 makeKeyWindow];
    
    NSLog(@"1当前所有的window %@",[UIApplication sharedApplication].windows);
}

2、但是将window设置成员变量就能够如期的看到window,代码如下

@interface ViewController ()
@property(nonatomic,strong)UIWindow *myWindow1;
@end

通过按钮响应事件调用test1方法,会发现创建的window显示出来了

// 将window设置成全局变量
- (void)test1
{
    self.myWindow1 = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.myWindow1.backgroundColor = [UIColor redColor];
    self.myWindow1.windowLevel = -1;
    self.myWindow1.hidden = NO;
}

也就是说window必须要设置成成员变量才能被显示出来吗?为什么?继续进行以下相关的测试:
3、没有声明成成员变量,单独创建的window类,直接调用没有显示

// 单独创建UIWindow类
- (void)test3
{
    MyWindow1 *myWindow = [[MyWindow1 alloc] initWithFrame:[UIScreen mainScreen].bounds];
    myWindow.backgroundColor = [UIColor greenColor];
    myWindow.windowLevel = 100;
    myWindow.hidden = NO;
    [myWindow makeKeyWindow];
}

4、单独创建UIWindow类,然后设置成全局变量,创建window之后有window显示

@interface ViewController ()
@property(nonatomic,strong)MyWindow1 *myWindow;
@end
- (void)test4
{
    self.myWindow = [[MyWindow1 alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.myWindow.backgroundColor = [UIColor greenColor];
    self.myWindow.windowLevel = 100;
    self.myWindow.hidden = NO;
    [self.myWindow makeKeyWindow];
}

5、创建单例window

+ (ShowWindow *)shareShowWindow
{
    static ShowWindow *window = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (window == nil) {
            window = [[ShowWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        }
    });
    
    return window;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor redColor];
        // 在window上面添加相关控件
        UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        tempBtn.frame = CGRectMake(100, 200, 100, 100);
        [tempBtn setTitle:@"点我消失" forState:UIControlStateNormal];
        tempBtn.backgroundColor = [UIColor greenColor];
        [tempBtn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:tempBtn];
    }
    return self;
}

- (void)clickBtn:(UIButton *)sender
{
    self.hidden = YES;
}

- (void)show
{
    [self makeKeyWindow];
    self.hidden = NO;
}

在ViewController中调用,创建的window显示了

// 创建window的单例进行实验
- (void)test5
{
    ShowWindow *window = [ShowWindow shareShowWindow];
    [window show];
}

总结:通过以上的实验可以总结出,并不是只有成员变量才可以,单例也可以,他们的共同点就是生命周期足够长。
这个时候产生一个疑问,单独创建的一个局部变量的button,添加在view上面怎么能够显示?UIWindow的父类虽然也是UIView,但是UIWindow的显示方式和view不一样。一般的view创建完了是需要添加到父控件上面的,对,就是这个"添加",父控件强引用了button,也就是button的引用计数+1了。
刚刚上面也说了,"创建的window是不需要添加到相关的控件的,只要创建就会添加到界面上",window并没有添加到任何的地方。
那么创建完了window可以找到吗?当然可以。通过以下代码可以找到创建的window。

NSLog(@"2当前所有的window %@",[UIApplication sharedApplication].windows);

我测试的时候也是这么观察的

- (void)clickBtn:(UIButton *)sender
{
    // 为了观察是不是新创建的window被当前的window挡住了
    AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
    app.window.alpha = 0.3;
    
    // 可以显示创建的window
    [self test1];
    
    // 不能正常显示创建的window
//    [self test2];
    
    // 不能正常的显示创建的window
//    [self test3];
    
    // 可以正常的显示创建的window
//    [self test4];
    
    // 可以正常显示创建的window
//    [self test5];
    
    NSLog(@"2当前所有的window %@",[UIApplication sharedApplication].windows);
}

在以上的实验中不同的方式添加window,添加完毕之后就可以查看windows中的情况了。
比如调用完了test1,打印[UIApplication sharedApplication].windows就会发现多一个window,并且可以和test1创建的window比较一下,确认是一个window。调用完test3,会发现没有添加新的window。
相关的Demo可以参考:https://github.com/RunOfTheSnail/UIWindowDemo

这是为什么?难道创建完了window没有被添加进[UIApplication sharedApplication].windows中吗?猜想,没有被添加进去,新创建的window没有被[UIApplication sharedApplication].windows强引用,很可能仅仅是弱引用。
做如下实验:
还是通过按钮的点击事件调用的。

// 测试创建的window和[UIApplication sharedApplication].windows的关系
- (void)test6
{
    self.myWindow2 = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.myWindow2.backgroundColor = [UIColor greenColor];
    self.myWindow2.windowLevel = 100;
    self.myWindow2.hidden = NO;
    [self.myWindow2 makeKeyWindow];
    NSLog(@"查看1   %@",[UIApplication sharedApplication].windows);
    self.myWindow2 = nil;
    NSLog(@"查看2   %@",[UIApplication sharedApplication].windows);
}

打印结果如下:这个和想要的结果不一样,想要的结果是第一次打印两个window,第二次打印一个window,有点演砸了。。。。。。。。

2016-10-14 10:06:57.459 UIWindowDemo[83896:1915917] 查看1   (
    "<UIWindow: 0x7fef83713620; frame = (0 0; 375 667); alpha = 0.3; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fef83714b40>; layer = <UIWindowLayer: 0x7fef83710f80>>",
    "<UIWindow: 0x7fef85010e30; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x7fef850122a0>; layer = <UIWindowLayer: 0x7fef85010570>>"
)
2016-10-14 10:06:57.460 UIWindowDemo[83896:1915917] 查看2   (
    "<UIWindow: 0x7fef83713620; frame = (0 0; 375 667); alpha = 0.3; autoresize = W+H; gestureRecognizers = <NSArray: 0x7fef83714b40>; layer = <UIWindowLayer: 0x7fef83710f80>>",
    "<UIWindow: 0x7fef85010e30; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x7fef850122a0>; layer = <UIWindowLayer: 0x7fef85010570>>"
)

但是得考虑一个问题。短时间window可能会不释放的问题,进行再一次的实验
创建另外一个测试按钮,通过点击事件来查看windows中的情况

 // 这个是配合着test6来测试的,查看windows数组的情况
    UIButton *myTempBtn = [UIButton buttonWithType:UIButtonTypeSystem];
    [myTempBtn setTitle:@"再点我,测试test2" forState:UIControlStateNormal];
    myTempBtn.frame = CGRectMake(100, 300, 300, 100);
    myTempBtn.backgroundColor = [UIColor greenColor];
    [myTempBtn addTarget:self action:@selector(clickMyTempBtn:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:myTempBtn];
- (void)clickMyTempBtn:(UIButton *)sender
{
    NSLog(@"查看3 %@",[UIApplication sharedApplication].windows);
}
 查看3 (
    "<UIWindow: 0x7faa09439ec0; frame = (0 0; 375 667); alpha = 0.3; autoresize = W+H; gestureRecognizers = <NSArray: 0x7faa0943af80>; layer = <UIWindowLayer: 0x7faa094369e0>>"

运行完test6之后,查看1和查看2打印的结果都是两个window,点击测试按钮之后,再次测试发现打印的是一个window,这下放心了。验证了自己的猜想。

总结:
1、创建的window不需要添加到任何的控件上就能显示,显示的规律是通过windowLevel的等级来显示的,相关参考:http://www.jianshu.com/p/f60471a7d935
2、新创建的window没有被[UIApplication sharedApplication].windows强引用,只是能通过[UIApplication sharedApplication].windows找到创建的window。所以想要创建的window显示,那就必须保证其生命周期。

以上是我自己根据相关的运行效果总结的,如果有哪位大神觉得有地方描述的不准确,欢迎指正哈,在下感激不尽!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容