Search code examples
iosmemory-managementretain

Non retained objects: when are they released?


Inside an initialization method, I have the following code

- (id)init {

    self = [super init];

    if (self) {

        UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        tempButton.frame = CGRectMake(0,0,300,44);

        // some custom code...

        self.myButton = tempButton;
    }

    return self;
}

Where myButton is a retained property. I know that, for what concerns memory management rules, this method equals this other:

- (id)init {

    self = [super init];

    if (self) {

        UIButton *tempButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,300,44)];

        // some custom code...

        self.myButton = tempButton;
        [tempButton release];
    }

    return self;
}

But in this case I need to use the first "version" because the buttonType property is readonly and I cannot change it after having the button initalized.

Since I find myself using the "non init-release" version in multiple methods all over my application, and for several object (most of them are NSString), my question is: not counting in this case the assignment to the property which retains the object, when the tempButton object will be released? Maybe at the end of the method/if statement? Or will the first "version" lead to an increased memory usage, since the object is not being released right away but after a certain amount of time?


Solution

  • I think you're a bit confused here: in both of your snippets, you create a tempButton object, but then you're assigning it to self.myButton. At that point, both tempButton and self.myButton are pointers to the same object. Now, presumably the myButton @property you're using is a strong property, so by assigning tempButton to it, you increase its retain count, and therefore in either version of the code it would have a retain count of +1 at the end, and would not be dealloc'ed.

    If, hypothetically, myButton wasn't a strong property, then there would be an error in your code, and in both cases tempButton would be prematurely released and dealloc'ed. Here's what would happen in the two cases:

    In your first version, since you're getting tempButton comes from something other than an init or copy method, it gets a retain count of +1, but is autoreleased. At the end of the current iteration of the run loop, the autorelease would kick in, bringing its retain count to 0 and causing it to be dealloc'ed.

    In the second version, you first get a tempButton with a retain count of 1 because it's coming from an init method. But later on you explicitly release it, bringing its retain count to 0, at which point it is immediately dealloc'ed.