6

In the Xcode templates for iOS apps such as the 'View Based Application', a MainWindow nib is created with contains three top-level objects: The App Delegate, the Window, and the main View Controller. The App Delegate defines retain outlets/accessors for both the window and the view controller. I don't understand why the App Delegate would need to retain these objects since they are already top-level objects in the nib and therefore should have been retained by UIApplication. Checking the retainCount of these objects sure enough shows 1 for the app delegate and 2 for the window and view controller. Could I/should I change these to assign instead?

I know this is a nit picky thing but I'm hoping that understanding why this is done will improve my overall understanding of memory management in iOS.

Marplesoft
  • 6,030
  • 4
  • 38
  • 46

2 Answers2

1

Assign is tricky in iOS with outlets I use @property (nonatomic, retain). Unlike in Mac OS, connected outlets to XIB objects in iOS are not automatically retained and memory managed, this may change with iOS 5, but is somewhat unlikely.

The rationale there is so that you can release any view objects in - (void)viewDidUnload, and get rid of any views that you either don't need, or can re-initialize on -(void)viewWillAppear. But the goal is, ostensibly, to keep you in control of what is collected and what is not.

my pattern is to just declare normal cocoa accessors for them as I would for any other properties and set them to nil in the viewDidUnload

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.buttonOne = nil;
    self.buttonTwo = nil;
    self.buttonThree = nil;
    self.buttonFour = nil;
    self.buttonFive = nil;
    self.buttonSix = nil;
    self.lineWidthSlider = nil;
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

You are right, however in that it doesn't really make much sense to have the retain for the window, but it makes sense for consistency IMHO. So long winded way of saying yes, in my experience the app delegate does need to retain the UIWindow or it can be collected in a memory sweep and cause somewhat random crashes.

Heat Miser
  • 19,438
  • 7
  • 35
  • 38
  • 1
    But doesn't UIApplication retain all top level objects in the nib including the Window? If so, then the window would never get cleaned up via a memory sweep unless the UIApplication released it (which I assume would only happen upon quitting the app). – Marplesoft Aug 17 '11 at 18:54
  • 1
    +1 It also cost nothing to retain the top window because it will never be deallocated as long as the app is running. – TechZen Aug 17 '11 at 18:55
  • 2
    UIApplication does retain the top window of the app, but when using VGA out you may have more than one window, so if you need to resignKeyWindow when working with it, I think you will need the retain. From apple's docs "You can create and configure your application’s main window programmatically or using Interface Builder. In either case, you create the window at launch time and should retain it and store a reference to it in your application delegate object." - https://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingWindows/CreatingWindows.html – Heat Miser Aug 17 '11 at 19:13
  • Fair enough. Good point on the VGA out scenario, I hadn't thought of that. – Marplesoft Aug 17 '11 at 21:47
0

It appears that the app delegate does need to retain the window UIWindow.

The default implementation of the application delegate in a new Xcode project includes:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

}

If you remove the window property and instead use a local variable, the app will launch to a black screen.

Xcode will also log the error:

[Application] The app delegate must implement the window property if it wants to use a main storyboard file.

The app delegate must implement the window property if it wants to use a main storyboard file swift


Setting the window property as weak will similarly launch a black screen. Xcode displays the error when you assign a UIWindow to the property:

Instance will be immediately deallocated because property 'window' is 'weak'

pkamb
  • 33,281
  • 23
  • 160
  • 191