iphonecocoa-touchpropertiessubview

iPhone Dev - Which way should a member be added as a subview


(We're talking about code inside custom UIViewController subclasses -- And by the way I don't use IB) Ok so I set the self.view member in - (void)loadView, and then I create my controls and views and whatever in - (void)viewDidLoad, and then add them to the subview. If the control isn't a member, if I create it and release it locally in the method, this is how I do it: (With a UILabel)

- (void)viewDidLoad {
    UILabel *localLabel = [[UILabel alloc] initWithFrame:CGRectMake(81, 384, 148, 21)];
    localLabel.text = @"I'm a Label!";
    localLabel.AutoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                  UIViewAutoresizingFlexibleRightMargin |
                                  UIViewAutoresizingFlexibleBottomMargin);

    [self.view addSubview:localLabel];
    [localLabel release];
    [super viewDidLoad];
}

Thats just an example of how I would create a label locally, set its properties, add to subview and release. But with a member, I do this:

UILabel *lblMessage;
...
@property (nonatomic, retain)UILabel *lblMessage;
...
- (void)viewDidLoad {
    UILabel *localMessage = [[UILabel alloc] initWithFrame:CGRectMake(81, 384, 148, 21)];
    localMessage.text = @"I'm a Label!";
    localMessage.AutoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                      UIViewAutoresizingFlexibleRightMargin |
                                      UIViewAutoresizingFlexibleBottomMargin);
    self.lblMessage = localMessage;
    [localMessage release];

    [self.view addSubview:lblMessage];
    [super viewDidLoad];
}

But I've also seen it done

...
- (void)viewDidLoad {
   UILabel *localMessage = [[UILabel alloc] initWithFrame:CGRectMake(81, 384, 148, 21)];
    localMessage.text = @"I'm a Label!";
    localMessage.AutoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
                                      UIViewAutoresizingFlexibleRightMargin |
                                      UIViewAutoresizingFlexibleBottomMargin);
    self.lblMessage = localMessage;

    [self.view addSubview:localMessage];
    [localMessage release];
    [super viewDidLoad];
}

like that in my beginning iPhone 3 development: exploring the sdk book. Notice adding the local variable, then releasing. Which should I do? Does it matter at all?


Solution

  • If lblMessage is a retaining property (which is often true), then there is no functional difference. Otherwise, the release-before-addSubview is a bug, since it will try to add a deallocated object as a subview.

    Here's a quick walkthrough of the reference count on localMessage, assuming the property lblMessage is retaining:

    UILabel *localMessage = [[UILabel alloc]...  // retainCount is now 1
    // Set up localMessage.  If you release'd now, you'd dealloc the object.
    self.lblMessage = localMessage;  // retainCount is now 2
    // You can safely call release now if you'd like.
    [self.view addSubview:localMessage];  // retainCount is now 3.
    [localMessage release];  // retainCount is now 2.
    

    You want the retainCount to end at 2, since you effectively have 2 references to that object - your member pointer lblMessage, and another retaining pointer in self.view.