Online Book Reader

Home Category

Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [41]

By Root 453 0

NSLog(@"Giving up ownership of one employee");

[employees removeObjectAtIndex:5];

NSLog(@"Giving up ownership of array");

employees = nil;

}

return 0;

}

Build and run the program. You should see something like this:

Employees: (

"",

"",

"",

"",

"",

"",

"",

"",

"",

""

)

Giving up ownership of one employee

deallocating

deallocating

deallocating

Giving up ownership of array

deallocating

deallocating

deallocating

deallocating

deallocing

When employee #5 is removed from the array, it is deallocated because it has no owner. Then its assets are deallocated because they have no owner. (And you’ll have to trust me on this: the labels (instances of NSString) of the deallocated assets are also deallocated once they have no owner.)

When employees is set to nil, the array no longer has an owner. So it is deallocated, which sets up an even larger chain reaction of memory clean-up and deallocation when, suddenly, none of the employees has an owner.

Tidy, right? As the objects become unnecessary, they are being deallocated. This is good. When unnecessary objects don’t get deallocated, you are said to have a memory leak. Typically a memory leak causes more and more objects to linger unnecessarily over time. The memory footprint of your application just gets bigger and bigger. On iOS, the operating system will eventually kill your application. On Mac OS X, the performance of the entire system will suffer as the machine spends more and more time swapping data out of memory and onto disk.

Challenge


Using the StockHolding class from a previous challenge, make a tool that creates an instance of a Portfolio class and fills it with stock holdings. A portfolio can tell you what its current value is.

20

Preventing Memory Leaks


It is pretty common to have relationships that go in two directions. For example, maybe an asset should know which employee is currently holding it. Let’s add that relationship. The new object diagram would look like this:

Figure 20.1 Adding holder relationship

From a design standpoint, you would say that we are adding a pointer from the child (an instance of Asset) back to its parent (the instance of Employee that is holding it).

In Asset.h, add a pointer instance variable to hold on to the holding employee:

#import

@class Employee;

@interface Asset : NSObject

{

NSString *label;

Employee *holder;

unsigned int resaleValue;

}

@property (strong) NSString *label;

@property (strong) Employee *holder;

@property unsigned int resaleValue;

@end

In Asset.m, synthesize the accessors and extend the description method to display the holder:

#import "Asset.h"

#import "Employee.h"

@implementation Asset

@synthesize label, resaleValue, holder;

- (NSString *)description

{

// Is holder non-nil?

if ([self holder]) {

return [NSString stringWithFormat:@"<%@: $%d, assigned to %@>",

[self label], [self resaleValue], [self holder]];

} else {

return [NSString stringWithFormat:@"<%@: $%d unassigned>",

[self label], [self resaleValue]];

}

}

- (void)dealloc

{

NSLog(@"deallocing %@", self);

}

@end

This brings us to a style question: When people use the Asset class and Employee class together, how do we make sure that the two relationships are consistent? That is, an asset should appear in an employee’s assets array if and only if the employee is the asset’s holder. There are three options:

Set both relationships explicitly:

[vicePresident addAssetsObject:townCar];

[townCar setHolder:vicePresident];

In the method that sets the child

Return Main Page Previous Page Next Page

®Online Book Reader