Monday, June 15, 2009

Memory Management: alloc vs. convenience constructor vs. accessor method. What is the difference and which is preferred?

The following simple examples illustrate the contrast between creating a new object using alloc, using a convenience constructor, and using an accessor method.

The first example creates a new string object using alloc: It must therefore be released.

- (void)printHello {
    NSString *string;
    string = [[NSString alloc] initWithString:@"Hello"];
    NSLog(string);
    [string release];
}

The second example creates a new string object using a convenience constructor: There is no additional work to do.

- (void)printHello {
    NSString *string;
    string = [NSString stringWithFormat:@"Hello"];
    NSLog(string);
}

The third example retrieves a string object using an accessor method: As with the convenience constructor, there is no additional work to do.

- (void)printWindowTitle {
    NSString *string;
    string = [myWindow title];
    NSLog(string);
}



According to Apple, using accessor methods is the preferred way to go. "Sometimes it might seem tedious or pedantic, but if you use accessor methods consistently the chances of having problems with memory
management decrease considerably. If you are using retain and release on instance variables throughout your code, you are almost certainly doing the wrong thing."

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html

Memory Management: rules to always keep in mind

  • Within a given block of code, the number of times you use copy, alloc and retain should equal the number of times you use release and autorelease.

  • You only own objects you created using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.

  • Implement a dealloc method to release the instance variables you own.

  • You should never invoke dealloc directly (other than when you invoke super’s implementation in a custom dealloc method).


http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html

Memory Management: “reference counting” methods

You manipulate the retain count (take and relinquish ownership) using a variety of methods:
alloc

Allocates memory for an object, and returns it with retain count of 1.

You own objects you create using any method that starts with the word alloc or with the word new.

copy

Makes a copy of an object, and returns it with retain count of 1.

If you copy an object, you own the copy. This applies to any method that contains the word copy where “copy” refers to the object being returned.

retain

Increases the retain count of an object by 1.

Takes ownership of an object.

release

Decreases the retain count of an object by 1.

Relinquishes ownership of an object.

autorelease

Decreases the reference count of an object by 1 at some stage in the future.

Relinquishes ownership of an object at some stage in the future.

The rules for memory management are summarized as follows (see also “Memory Management Rules”):

  • Within a given block of code, the number of times you use copy, alloc and retain should equal the number of times you use release and autorelease.

  • You only own objects you created using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.

  • Implement a dealloc method to release the instance variables you own.

  • You should never invoke dealloc directly (other than when you invoke super’s implementation in a custom dealloc method).


http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html

Memory Management: “reference counting” overview

Cocoa implements its ownership policy through a mechanism called “reference counting” or “retain counting.” When you create an object, it has a retain count of 1. When you send an object a retain message, its retain count is increased by 1. When you send an object a release message, its retain count is decreased by 1 (autorelease causes the retain count to be decremented in the future).

When its retain count drops to 0, an object’s memory is reclaimed—in Cocoa terminology it is “freed” or “deallocated.” When an object is deallocated, its dealloc method is invoked automatically. The role of the dealloc method is to free the object's own memory, and dispose of any resources it holds, including its object instance variables.

If your class has object instance variables, you must implement a dealloc method that releases them, and then invokes super's implementation. For example, if the Thingamajig class had name and sprockets instance variables, you would implement its dealloc method as follows:

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

You should never invoke another object’s dealloc method directly.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043-BEHDEDDB

Implementing Accessor Methods: @synthesize

In many cases you can (and should) avoid the need to implement your own accessor methods by using the Objective-C declared properties feature and asking the compiler to synthesize accessor methods for you:

@synthesize firstName;
@synthesize fullName;
@synthesize birthday;
@synthesize luckyNumber;

Even if you need to provide your own implementation, you should declare accessors using a declared property—you must ensure, of course, that your implementation meets the specification you give. (Note in particular that by default a declared property is atomic; if you don’t provide an atomic implementation, you should specify nonatomic in the declaration.)

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW1

Declaring Accessor Methods: @property

You should typically use the Objective-C declared properties feature to declare accessor methods (see Declared Properties in The Objective-C 2.0 Programming Language), for example:

@property (copy) NSString *firstName;
@property (readonly) NSString *fullName;
@property (retain) NSDate *birthday;
@property NSInteger luckyNumber;

The declaration makes explicit the memory management semantics for the property.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW1