Skip to content

IBOutlets as Properties and Memory Management in iOS 5 SDK

December 22, 2011

Private properties

If you look at the code of many iOS developers who developed for Cocoa before iOS, you’re likely to see a common pattern. IBOutlets were simply declared as ivars and then can be referenced in the class and connected in the IB files (which I will call “nibs” because I never got comfortable pronouncing “xib”).

@interface MyViewController : NSObject
{
    IBOutlet NSButton* submitButton;
}
@end

I always felt that the public variables of a class should help define the “state” of the class. In the case of controllers with connections to nibs, I don’t think that many of the objects declared as IBOutlets needed to be declared as public variables. The question I often asked myself is why would some object outside of the controller need to know the state or need to change the state of the objects declared as IBOutlets. When there is no answer (as often is the case), I would declare them after @private or @protected in the header.

Now with Objective-C 2.0 and the introduction of properties, synthesized variables, and automatic reference counting (“ARC”), Apple seems to be eliminating the need to declare ivars. Well what about properties that you want to keep hidden from the public interface. The solution is to use an unnamed category in your implementation file.

@interface MyViewController ()
@property (strong, nonatomic) IBOutlet UIButton* submitButton;
@end
@implementation MyViewController

@synthesize submitButton;

// rest of the implementation

@end

You can now connect this IBOutlet in Interface Builder yet keep the property “private.”

Memory Management of IBOutlets

Developers must manage the allocation of memory of IBOutlets referenced in instances of UIViewController (or its subclasses). The preferred method differs depending on whether ARC is being used or not. I would suggest that if you are developing for iOS 5 or later, use ARC.

IBOutlet Memory Management with ARC

If I am developing for iOS 5, I will use ARC and handle my IBOutlets like so. First, I will decade the property for the IBOutlet as I discussed above. Second, I will synthesize the getters & setters (the ivars are synthesized automatically). Finally, in -viewDidUnload I will set the value of the property to nil.

@interface MyViewController ()
@property (strong, nonatomic) IBOutlet UIButton* submitButton;
@end
@implementation MyViewController

@synthesize submitButton;

- (void)viewDidUnload
{
    [self setSubmitButton:nil];
// You can also use self.submitButton = nil; but I'm old-school

    [super viewDidUnload];
}

@end

IBOutlet Memory Management without ARC

If I am developing for iOS 4 or earlier or for some other reason, can’t use ARC, I will handle my IBOutlets like so. First, I will decade the property for the IBOutlet as I discussed above. Second, I will synthesize the getters & setters and set the ivar manually. Finally, in -dealloc I will release the ivar.

@interface MyViewController ()
@property (retain, nonatomic) IBOutlet UIButton* submitButton;
@end
@implementation MyViewController

@synthesize submitButton = _submitButton;

- (void)dealloc
{
    [_submitButton release];
// Apple advises against using accessors in dealloc methods

    [super dealloc];
}

@end

I like to put the dealloc right after my @synthesize statements so that I can make sure that I released everything I created.

Advertisements
Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: