Mr_Vlasov
Mr_Vlasov

Reputation: 537

"for" loop from program 7.6 from Kochan's "Programming in Objective-C"

"The sigma notation is shorthand for a summation. Its use here means to add the values of 1/2^i, where i varies from 1 to n. That is, add 1/2 + 1/4 + 1/8 .... If you make the value of n large enough, the sum of this series should approach 1. Let’s experiment with different values for n to see how close we get."

#import <Foundation/Foundation.h>
// Define the Fraction class
@interface Fraction : NSObject
{
int numerator;
int denominator;
}
@property int numerator, denominator;
-(void) print;
-(void) setTo: (int) n over: (int) d;
-(Fraction*) add: (Fraction *) f;
-(void) reduce;
@end    

#import "Fraction.h"
@implementation Fraction
@synthesize numerator, denominator;
-(void) print
{
NSLog (@"%i/%i", numerator, denominator);
}
-(void) setTo: (int) n over: (int) d
{
numerator = n;
denominator = d;
}
-(Fraction *) add: (Fraction *) f
{
// To add two fractions:
// a/b + c/d = ((a*d) + (b*c)) / (b * d)
// result will store the result of the addition
Fraction *result = [[Fraction alloc] init];
result.numerator = numerator * f.denominator +
denominator * f.numerator;
result.denominator = denominator * f.denominator;
[result reduce];
return result; 
}

#import "Fraction.h"
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *aFraction = [[Fraction alloc] init];
Fraction *sum = [[Fraction alloc] init], *sum2;
int i, n, pow2;
[sum setTo: 0 over: 1]; // set 1st fraction to 0
NSLog (@"Enter your value for n:");
scanf ("%i", &n);
pow2 = 2;

for (i = 1; i <= n; ++i) {
[aFraction setTo: 1 over: pow2];
sum2 = [sum add: aFraction];
[sum release]; // release previous sum
sum = sum2;
pow2 *= 2;
}

NSLog (@"After %i iterations, the sum is %g", n, [sum convertToNum]);
[aFraction release];
[sum release];
[pool drain];
return 0;
}

Question: Why do we have to create additional variable sum2 that we are using in the "for" loop? Why do we need "release previous sum" here and then again give it a value that we just released? :

sum2 = [sum add: aFraction];
[sum release]; // release previous sum
sum = sum2;

Is it just for the sake of avoiding memory leakage? (method "add" initializes a variable that is stored in sum2)

Upvotes: 0

Views: 145

Answers (2)

Tommy
Tommy

Reputation: 100622

Without knowing the Fraction class that is most likely part of the book, it's likely just an example of immutable object usage.

Immutable objects are generally advocated because:

  • it's easy to make them thread safe; and
  • because they're guaranteed not to change everyone can reliably hold onto the same one rather than copying the value ad nauseam.

So you can multiprocess to your heart's content and in any reasonably complex system you usually save memory while remaining object oriented (ie, each object is sovereign and nobody else directly manipulates an object's internal data).

Being immutable, you have to create a new one when you want to 'modify' an existing one, which I think is what's going on here.

EDIT: with the full source for Fraction being given it looks like the object is actually mutable (eg, it has setTo:over:). So the answer is still that the old object is thrown away and the new one kept because the add: doesn't mutate the object it's called on but rather returns a new object with the net result. Stylistically though it seems more like a pursuit of three address form than the immutable object pattern.

Upvotes: 1

Isaac
Isaac

Reputation: 10834

Without seeing how Fraction is defined, I can't be sure, but I'd guess that a Fraction object is immutable so that sum can't simply be changed. If we did sum = [sum add:aFraction], it would leak the object that sum used to point to (it had a positive retain count, still does, and we no longer have a pointer to it).

Upvotes: 2

Related Questions