May 27, 2014

Fast food objective-c (part 6) : Class Implementation

Class Implementation

Let's create an implementation, starting with the getters:
#import "Photo.h"

@implementation Photo
    
- (NSString*) caption {
    return caption;
}

- (NSString*) photographer {
    return photographer;
}

@end

This part of the code starts with @implementation and the class name, and has @end, just like the interface. All methods must appear between these two statements. 
The getters should look very familiar if you've ever written code, so let's move on to the setters, which need a bit more explanation:
 - (void) setCaption: (NSString*)input
{
    [caption autorelease];
    caption = [input retain];
}

- (void) setPhotographer: (NSString*)input
{
    [photographer autorelease];
    photographer = [input retain];
}
Each setter deals with two variables. The first is a reference to the existing object, and the second is the new input object. In a garbage collected environment, we could just set the new value directly:
 - (void) setCaption: (NSString*)input {
    caption = input;
}  
But if you can't use garbage collection, you need to release the old object, and retain the new one. 
There are actually two ways to free a reference to an object: release and autorelease. The standard release will remove the reference immediately. The autorelease method will release it sometime soon, but it will definitely stay around until the end of the current function (unless you add custom code to specifically change this). 
The autorelease method is safer inside a setter because the variables for the new and old values could point to the same object. You wouldn't want to immediately release an object which you're about to retain. 
This may seem confusing right now, but it will make more sense as you progress. You don't need to understand it all yet.

Init

We can create an init method to set inital values for our instance variables:
 - (id) init
{
    if ( self = [super init] )
    {
        [self setCaption:@"Default Caption"];
        [self setPhotographer:@"Default Photographer"];
    }
    return self;
}
This is fairly self-explanatory, though the second line may look a bit unusual. This is a single equals sign, which assigns the result of [super init] to self
This essentially just asks the superclass to do its own initialization. The if statement is verifying that the initialization was successful before trying to set default values.

Dealloc

The dealloc method is called on an object when it is being removed from memory. This is usually the best time to release references to all of your child instance variables:
 - (void) dealloc
{
    [caption release];
    [photographer release];
    [super dealloc];
}
On the first two lines, we just send release to each of the instance variables. We don't need to use autorelease here, and the standard release is a bit faster. 
The last line is very important. We have to send the message
[super dealloc] to ask the superclass to do its cleanup. If we don't do this, the object will not be removed, which is a memory leak. 
The dealloc method is not called on objects if garbage collection is enabled. Instead, you implement the finalize method.

No comments:

Post a Comment