George
George

Reputation: 3619

Can I release an object after autorelease in Objective-C 2.0

My development environment:

Xcode 4.6.2

non-Automatic Reference Counting

For example, suppose we have a view controller called CertainViewController.m, where a property called certainProperty with attributes retain and nonatomic is declared.

// CertainViewController.h
@interface CertainViewController : UIViewController
{
}
@property (retain, nonatomic) certainPropertyClass *listData;

// CertainViewController.m
- (void) viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    self.certainProperty = [[[certainPropertyClass alloc] init] autorelease];
    // Among other initialization...
}

In the dealloc method, there is implicit release when we assign a new value to the the property certainProperty. Not sure this is potentially hazardous or not.

// CertainViewController.m
- (void) dealloc
{
    self.certainProperty = nil;
}

Please share some insight, thank you :D

Upvotes: 0

Views: 231

Answers (4)

Mohannad A. Hassan
Mohannad A. Hassan

Reputation: 1648

Stick to the convention. Don't defy the usual memory model unless there's something really important that can't be done otherwise.

release decreases the retain count by 1. So it's not safe to call release for it. One other object may have retained this, so the retain count is 1. So calling release may cause it to be deallocated. That's in general.

If you have a retain property, then assigning an object to it will result in retaining that object.

self.retainProperty = [[[MyObject alloc] init] autorelease] Will result in retainCount = 1.

Note: The way you initialize certainProperty in viewDidLoad: is wrong. alloc is a class method, it actually returns a new allocated object. So [[[self.certainProperty alloc] init] autorelease]; Will not set your property. Do as xlc said in his answer.

Upvotes: 1

Bryan Chen
Bryan Chen

Reputation: 46578

First, you code is wrong

// CertainViewController.m
- (void) viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    //[[[self.certainProperty alloc] init] autorelease]; // this is a nop if self.certainProperty is nil or crash if not nil
    self.certainProperty = [[[YourPropertyClass alloc] init] autorelease];
    // Among other initialization...
}


// CertainViewController.m
- (void) dealloc
{
    self.certainProperty = nil;
    [super dealloc]; // you must call super
}

Second, assuming certainProperty is a retained property, assign a value to it will call retain by the setter.

So doing

self.certainProperty = nil;

in dealloc is required to balance the retain count otherwise certainProperty will be leaked.

Upvotes: 3

James Sumners
James Sumners

Reputation: 14775

If you put it in the autorelease pool then you should let autorelease take care of it. Personally, I would handle the releasing of the object myself unless it requires an autorelease pool (say, some GUI object reference). But setting it to nil is not a problem. You can perform operations all day long on a nil object with no side effects.

Upvotes: 1

The Kraken
The Kraken

Reputation: 3158

It's not strictly hazardous to release a variable with autorelease in a non-ARC environment. However, it's not considered great practice to just tag on autorelease to variables that you could manually release just as easily. autorelease is really meant to be used when you want to get rid of an object as soon as the system no longer needs it, usually at a time you won't know. So while your code isn't strictly invalid, just know that it's best to manually call release when you know exactly when to release an object, such as in your -dealloc method.

Upvotes: 1

Related Questions