-2

I am setting up a basic geometry class where I define a rectangle and can manipulate the width and height along with calculating the area and perimeter. Everything works and outputs fine, except the perimeter and area variables return as zero. I don't know how to set the variable properly within itself or during the @implementation, so I'm sure it is showing the zero from when the variable is first initialized (before the width and height are set).

I'm inexperienced with OOP and ObjC so I may be missing something simple.

#import <Foundation/Foundation.h>

// @interface setup as required.
@interface Rectangle: NSObject
-(void) setWidth: (int) w;
-(void) setHeight: (int) h;
-(int) width;
-(int) height;
-(int) area;
-(int) perimeter;
-(void) print;
@end

// @implementation setup for the exercise.
@implementation Rectangle {
    int width;
    int height;
    int perimeter;
    int area;
}
// Set the width.
-(void) setWidth: (int) w {
    width = w;
}
// Set the height.
-(void) setHeight: (int) h {
    height = h;
}

// Calculate the perimeter.
-(int) perimeter {
    return (width + height) * 2;
}

// Calculate the area.
-(int) area {
    return (width * height);
}

-(void) print {
    NSLog(@"The width is now: %i.", width);
    NSLog(@"The height is now: %i.", height);
    NSLog(@"The perimeter is now: %i.", perimeter);
    NSLog(@"The area is now: %i.", area);
}
@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        // Create an instance of Rectangle.
        Rectangle *theRectangle;
        theRectangle = [Rectangle alloc];
        theRectangle = [theRectangle init];
        // Use the designed methods.
        [theRectangle setWidth: 100];
        [theRectangle setHeight: 50];
        [theRectangle print];
    }
    return 0;
}
jscs
  • 63,694
  • 13
  • 151
  • 195
user3223880
  • 65
  • 1
  • 10
  • don't use ivar, make them property – Bryan Chen Sep 09 '14 at 23:39
  • Are you following an old tutorial? This class declaration doesn't use modern functionality. – jscs Sep 09 '14 at 23:42
  • Yes. Out of a book I picked up and using some generalized exercises in it. Thanks for the heads up. I would rather learn properly like you're speaking of than something antiquated from a book. Know of any good resources to check out? – user3223880 Sep 09 '14 at 23:48
  • Have a look at [Good resources for learning ObjC](http://stackoverflow.com/q/1374660). The Big Nerd Ranch books are excellent, and lots of people like the Stanford iOS course on iTunes U. – jscs Sep 10 '14 at 00:00

1 Answers1

0

Short answer:

Call your object methods like this:

 [self perimeter];
 // as in
 NSLog(@"The perimeter is now: %i.", [self perimeter]);

instead of just

 perimeter

which accesses the variable with that name, instead of calling the method you've defined.

Longer answer:

There are several things in your code that can be improved:

You should use properties instead of ivars and methods to get and set them. A property declared like this: @property (nonatomic) int width; will give you a getter and a setter, created implicitly by the compiler. So then you can do either of these to set a value:

theRectangle.width = 100;
// is the same as:
[theRectangle setWidth:100];

You can override your getters and setters too. You could also create readonly properties, e.g.

@interface Rectangle: NSObject

@property (nonatomic) int width;
@property (nonatomic) int height;
@property (nonatomic, readonly) int perimeter;

@end

@implementation Rectangle

- (int)perimeter
{
    return self.width * self.height * 2;
}

@end
TotoroTotoro
  • 17,524
  • 4
  • 45
  • 76
  • I saw that @property during some research and thought about applying it, I just didn't understand how. Thank you for a quick, concise and clear answer. – user3223880 Sep 09 '14 at 23:50
  • @user3223880 you're welcome. I just expanded my answer a little, by the way. – TotoroTotoro Sep 09 '14 at 23:58