Area and perimeter are just methods - the only instance variables for a Rectangle should be its width and height. By including area and perimeter as integer ivars in your @implementation section you've created ambiguity between the methods area and perimeter - which calculate those values dynamically when called - and the instance variables which are never set correctly in your code.

The code produces the right results because there are no getter methods for the ivars area and perimeter, so the method is called instead. But really area and perimeter need to be removed, unless you're going to constantly update them as the user changes the height and width of the rectangle (which would be unnecessary as these values can be generated dynamically from the width and height alone).

When working with objects, ask yourself: what are the intrinsic properties of this object? If you know the width and height of a rectangle, you can calculate the area or the perimeter, so only the width and height are intrinsic and only they should be ivars. But even if you wanted to store non-intrinsic ivars, you should make setter and getter methods for them and ensure they're updated based on changes made to other properties of the object.

Area and perimeter are just methods - the only instance variables for a Rectangle should be its width and height. By including area and perimeter as integer ivars in your @implementation section you've created ambiguity between the methods area and perimeter - which calculate those values dynamically when called - and the instance variables which are never set correctly in your code.

The code produces the right results because there are no getter methods for the ivars area and perimeter, so the method is called instead. But really area and perimeter need to be removed, unless you're going to constantly update them as the user changes the height and width of the rectangle (which would be unnecessary as these values can be generated dynamically from the width and height alone).

When working with objects, ask yourself: what are the intrinsic properties of this object? If you know the width and height of a rectangle, you can calculate the area or the perimeter, so only the width and height are intrinsic and only they should be ivars. But even if you wanted to store non-intrinsic ivars, you should make setter and getter methods for them and ensure they're updated based on changes made to other properties of the object.

Are you saying that they shouldn't appear in the @interface section at all? The exercise in the text shows them in the @interface section.

Here's what I have on this exercise, but I did notice that the way you call variables differs from mine in the NSLog in main:

Code: (Objective-C)

// Suppose you are developing a library of routines to // manipulate graphical objects. Start by defining a new class // called Rectangle. For now, just keep track of the rectangle’s // width and height. Develop methods to set the rectangle’s width // and height, retrieve these values, and calculate the rectangle’s // area and perimeter. Assume that these rectangle objects describe // rectangles on an integral grid, such as a computer screen. In // that case, assume that the width and height of the rectangle are// integer values.//// Here is the @interface section for the Rectangle class:// @interface Rectangle: NSObject // -(void) setWidth: (int) w; // -(void) setHeight: (int) h; // -(int) width;// -(int) height; // -(int) area; // -(int) perimeter; // @end//// Write the implementation section and a test program to test your new class and methods.