UIScreen vs UIWindow

// Create and configure the UIWindow instance // A CGRect is a struct with an origin (x, y) and a size (width, height) 
CGRect winFrame = [[ UIScreen mainScreen] bounds]; 
UIWindow *theWindow = [[ UIWindow alloc] initWithFrame:winFrame]; 
self.window = theWindow;

The above is not entirely clear yet to me, can someone please outline why we seem to

  1. Create a frame based on screen dimensions
  2. Then create a UIwindow / frame based on those screen dimensions
  3. Then use the line self.window

What is happening here as lines 2 & 3 seem to duplicate each other ?

There is no duplication. Line 2 is creating a window object to fill the entire screen. The application needs a window object to host its root view. Line 3 is giving the application its window object.

Cheers, but that’s on part what I mean, the differences between line 2 and 3 seem very subtle to me.

Creating an object and giving the application its object seem to overlap,

Can anyone detail the difference, even as ELI5 if preferred.

PS maybe it’s my misunderstanding of the self.window line.

In that case, I strongly recommend that you put the BNR book aside for a while and read this: Programming with Objective-C.

Please also remember that since Objective-C is a superset of the C Programming Language, you are expected to be at least very familiar with that language.

Also try the following practical exercise to see if it helps to clarify things a bit.

Run your code with three different versions of the application:didFinishLaunchingWithOptions: method: and try to explain what’s happening in each case.

Version 1 - Will crash your program

// Test to see if the window object is set
//
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    assert (self.window != nil);

    return YES;
}

Version 2 - Will also crash your program

// Test to see if the window object is set
//
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    CGRect winFrame = [[ UIScreen mainScreen] bounds]; 
    UIWindow * theWindow = [[ UIWindow alloc] initWithFrame:winFrame]; 
    assert (self.window != nil);

    return YES;
}

Version 3

// Test to see if the window object is set
//
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    CGRect winFrame = [[ UIScreen mainScreen] bounds]; 
    UIWindow * theWindow = [[ UIWindow alloc] initWithFrame:winFrame]; 
    self.window = theWindow;
    assert (self.window != nil);

    return YES;
}

I hope you enjoy the learning process :slight_smile:

To take an aside stab at this (ibex10’s advice, as usual, is super solid), here’s what’s going on above.
Imagine a really smart, robotic house is following a blueprint and building itself up. It needs to install a door.
Line 1 figures out how big the door needs to be, by examining the size of the doorframe.
Line 2 actually constructs a door to the specified dimensions.
Line 3 installs the door into the house’s wall: “my door shall be this door right here”.

Thank you ibex10, my understanding of Objective-C is somewhat further along than I might be projecting, though some concepts are under refinement :slight_smile:

I can look further at those examples sent.

This is brilliant Mikey, just what I needed, the object needed to be ‘used’ not just created.

Thanks