Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C Properties and Memory Management

Given the following property definition:

@property (nonatomic,retain) MyObject* foo;

does the following code cause a memory leak:

self.foo = [[MyObject alloc] init];

?

It looks like the alloc call increments the retain count on the object to 1, then the retain inside the property setter increases it to 1. But since the initial count is never decremented to 0, the object will stick around even when self is released. Is that analysis correct?

If so, it looks like I have two alternatives:

self.foo = [[[MyObject alloc] init] autorelease];

which is not recommended on the iPhone for performance reasons, or:

MyObject* x = [[MyObject alloc] init];
self.foo = x
[x release];

which is a bit cumbersome. Are there other alternatives?

like image 750
Bill Avatar asked Feb 18 '10 22:02

Bill


People also ask

Does Objective-C have memory management?

Objective-C provides two methods of application memory management. In the method described in this guide, referred to as “manual retain-release” or MRR, you explicitly manage memory by keeping track of objects you own.

What are Objective-C properties?

The Objective-C declared properties feature provides a simple way to declare and implement an object's accessor methods.

What is the purpose of memory management?

Memory management is the process of controlling and coordinating a computer's main memory. It ensures that blocks of memory space are properly managed and allocated so the operating system (OS), applications and other running processes have the memory they need to carry out their operations.

Is Objective-C memory Safe?

What's important to understand about Objective-C' safety is that it uses null pointers. The pointer is the component of C++ and other C-based languages and it can cause vulnerabilities in security. It's the method for exposing values that gives developers higher access to the data.


2 Answers

Are there any alternatives?

No.

You are not going to be able write much of an iPhone application without using autorelease and the Cocoa Touch library uses them in many places. Understand what it's doing (adding the pointer to a list for removal on the next frame) and avoid using it in tight loops.

You can use class method on MyObject that does alloc/init/autorelease for you to clean it up.

+ (MyObject *)object {
    return [[[MyObject alloc] init] autorelease];
}

self.foo = [MyObject object];
like image 108
Gerry Shaw Avatar answered Oct 27 '22 03:10

Gerry Shaw


The easiest way to manage a retained property on the iPhone is the following (autorelease is not as bad as you think, at least for most uses):

-(id)init {
    if (self = [super init]) {
        self.someObject = [[[Object alloc] init] autorelease];
    }
    return self;
}

-(void)dealloc {
    [someObject release];
    [super dealloc];
}

The autorelease releases the reference to the floating instance which is assigned to self.object which retains its own reference, leaving you with the one reference you need (someObject). Then when the class is destroyed the only remaining reference is released, destroying the object.

As described in another answer, you can also create one or more "constructor" messages to create and autorelease the objects with optional parameters.

+(Object)object;
+(Object)objectWithCount:(int)count;
+(Object)objectFromFile:(NSString *)path;

One could define these as:

// No need to release o if fails because its already autoreleased
+(Object)objectFromFile:(NSString *)path {
    Object *o = [[[Object alloc] init] autorelease];
    if (![o loadFromFile:path]) {
        return nil;
    }
    return o;
}
like image 45
Nick Bedford Avatar answered Oct 27 '22 01:10

Nick Bedford