UIWindow makeKeyAndVisible doesn't play well with ARC

I am recreating some kind of UIAlertView to my application, so I will subclass UIWindow to do this. The window is added to [UIApplication sharedApplication].windows , but it never actually displays. I trimmed it to this small piece of code:

 UIWindow *testWindow = [[UIWindow alloc] initWithFrame:self.view.bounds]; testWindow.backgroundColor = [UIColor blueColor]; [testWindow makeKeyAndVisible]; 

When I write [UIApplication sharedApplication].windows , I see:

 "<UIWindow: 0x83774f0; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x8377660>>", "<UIWindow: 0x8382630; frame = (0 0; 300 400); layer = <UIWindowLayer: 0xf573e60>>" 

And yet, the second window with a blue background is now not visible.

UPDATE : this seems to be a problem only with ARC enabled. I created 2 new projects of a “single view”, one with ARC turned on and the other with ARC turned off. Both are identical, and I add the UIWindow code to viewDidAppear: main view controller. When I launch applications in the simulator, a blue window appears only in the project with ARC disabled. It seems like ARC is getting rid of my UIWindow too quickly, so it doesn't even have time to appear. __strong did not help to do this. Still clueless ...

+4
source share
2 answers

It seems that ARC is getting rid of my UIWindow too quickly, and therefore it doesn’t even have time to appear. __strong did not help to do this.

Creating what __strong ? The variable indicated in your question is a local variable that exists only until the method returns. When the method returns, the variable leaves, so nothing belongs to the window, so it will be freed.

Assign the window pointer to the __strong instance __strong or the strong property. Then you will have a longer possession, retaining the window. Set ivar or property to nil after you release the window.

As a note, are you sure you want this to be a subclass of UIWindow, not UIView? Even UIAlertView is a view, not a window. If he creates his own window, you can do this - have a view that creates your own window as an implementation detail.

+11
source
  • The docs mention that you should use UIScreen to define borders: [[UIScreen mainScreen] bounds]
  • I'm not sure if this is necessary, but you are not adding a UIView to your window.
  • I noticed opaque = NO - try [window setOpaque:NO]; or something similar.
  • I checked your code and got:

    In application windows, it is expected that the root controller will be installed at the end of the application launch.

    So use [window setRootViewController:...]; . Do not ask me why this really does not seem to me necessary.

0
source

Source: https://habr.com/ru/post/1388371/


All Articles