Fraction.h

#import <Foundation/Foundation.h>

@interface Fraction : NSObject {

int numerator;

int denominator;

}

@property int numerator, denominator;

-(void) print;

-(void) reduce;

-(void) setTo: (int) n over: ( int) d;

-(double) convertToNum;

@end

Fraction.m

#import "Fraction.h"

@implementation Fraction

@synthesize numerator, denominator;

-(void) print

{

NSLog(@"%i/%i", numerator, denominator);

}

-(void) reduce

{

int u = numerator, v = denominator, temp;

while (u) {

temp = v % u;

v = u;

u = temp;

}

numerator /= v;

denominator /= v;

}

-(void) setTo: (int) n over: ( int) d

{

self.numerator = n;

self.denominator = d;

}

-(double) convertToNum

{

if ( denominator )

return (double) numerator/ denominator;

else

return 0.00;

}

@end

MathOps.h

#import "Fraction.h"

@interface Fraction (MathOps)

-(Fraction *) add: (Fraction *) f;

-(Fraction *) mul: (Fraction *) f;

-(Fraction *) sub: (Fraction *) f;

-(Fraction *) div: (Fraction *) f;

@end

Mathops.m

Does it matter **where** the autorelease message is invoked? I saw that in the answer Steve gave for the first edition, it was with the return statement, like this:

return [result autorelease]

If I understand the book correctly, **when** the autorelease message is sent should not matter. Is it a matter of style, or is one correct and one incorrect?

#import "Mathops.h"

@implementation Fraction (MathOps)

-(Fraction *) add: (Fraction *) f

{

Fraction *result = [ [ [ Fraction alloc] init] autorelease];

int resNumerator = numerator * f.denominator + f.numerator* denominator;

int resDenominator = denominator * f.denominator;

[result setTo: resNumerator over:resDenominator];

[result reduce];

return result;

}

-(Fraction *) mul: (Fraction *) f

{

Fraction *result = [ [ [ Fraction alloc] init] autorelease];

int resNumerator = numerator * f.numerator;

int resDenominator = denominator * f.denominator;

[result setTo: resNumerator over:resDenominator];

[result reduce];

return result;

}

-(Fraction *) sub: (Fraction *) f

{

Fraction *result = [ [ [ Fraction alloc] init] autorelease];

int resNumerator = numerator * f.denominator - f.numerator* denominator;

int resDenominator = denominator * f.denominator;

[result setTo: resNumerator over:resDenominator];

[result reduce];

return result;

}

-(Fraction *) div: (Fraction *) f

{

Fraction *result = [ [ [ Fraction alloc] init] autorelease];

int resNumerator = numerator * f.denominator;

int resDenominator = denominator * f.numerator;

[result setTo: resNumerator over:resDenominator];

[result reduce];

return result;

}

@end

Test program main.m

#import "Fraction.h"

#import "Mathops.h"

int main (int argc, const char * argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

int a = 1, b = 2, c = 1, d = 4;

NSLog(@"Given \"a = %i\", \"b = %i\", \"c = %i\", \"d = %i\"", a, b, c, d);

NSLog(@"Set \"myF to %i/%i\"", a, b);

NSLog(@" and \"myF2 to %i/%i\"", c, d);

Fraction *myF = [[[Fraction alloc] init ] autorelease];

Fraction *myF2 = [ [ [ Fraction alloc] init] autorelease];

NSLog(@"print \"myF\"");

[myF setTo:a over:b];

[myF print];

NSLog(@"reduce \"myF\"");

[myF reduce];

[myF print];

NSLog(@"convert myF To number");

NSLog(@"= %g", [myF convertToNum]);

[myF setTo: a over: b];

[myF2 setTo: c over: d];

NSLog(@"Perform \"[[myF add: myF2] print ]\"");

[[myF add: myF2] print ];

[myF setTo: a over: b];

[myF2 setTo: c over: d];

NSLog(@"Perform \"[[myF mul: myF2] print ]\"");

[[myF mul: myF2] print ];

[myF setTo: a over: b];

[myF2 setTo: c over: d];

NSLog(@"Perform \"[[myF div: myF2] print ]\"");

[[myF div: myF2] print ];

[myF setTo: a over: b];

[myF2 setTo: c over: d];

NSLog(@"Perform \"[[myF sub: myF2] print ]\"");

[[myF sub: myF2] print ];

[myF release];

NSLog(@"Release myF. If it crashes..which it should , proves it is already released???");

NSLog(@"I get: \"EXC_BAD_ACCESS\" if I continue program.");

[pool drain];

return 0;

}