Dr.P
Dr.P

Reputation: 97

Classes owning their objects

Question: I understand that origin is an instance variable of the Rectangle class which has the XYPoint type. The origin instance variable has two other instance variables x and y. I don't understand clearly, what the if statement in the rectangle class does?

I believed that the if (! origin) means if the origin is not equal to zero then do the following... Is the origin equal to zero? if yes how is it equal to zero and how is it validated in the if (! origin) statement. In other words what does the if (! origin) statement do?

Is there an instance where the origin is equal to zero? if this occurs, how will my code respond? I know that without the if statement myPoint object will not retain its initial value.

I will also like to know why we used the class directive in rectangle class rather than import. What difference does it make. I also noticed that we didn't import the XYPoint header at the rectangle's implementation. I will be very grateful if anyone is willing to help. Thanks a lot in advance.

NB: Please take a look at my codes below.


* XYPoint Class

 #import <Foundation / Foundation.h>

 @interface XYPoint: NSObject

 @property int x, y;

 -(void) setX: (int) Xval andY: (int) yVal;
 @end

 #import "XYPoint.h"

 @implementation  XYPoint

 @synthesize x, y;

 -(void) setX: (int) Xval andY: (int) yVal
  { x = xVal;
    y = yVal;
  }
  @end

* Rectangle Class

#import <Foundation/Foundation.h>

@class XYPoint;
@interface Rectangle: NSObject

-(XYPoint *) origin;
-(void) setOrigin: (XYPoint *) pt;
@end

#import "Rectangle.h"

@implementation Rectangle
{ 
 XYPoint *origin
}

 -(void) SetOrigin: (XYPoint *) pt
{
 if (! origin)
 origin = [[XYPoint alloc]init];
 origin.x = pt.x;
 origin.y = pt.y;
}

-(XYPoint *) origin
{
  return origin;
}
@end

Main

#import "Rectangle.h"
#import "XYPoint.h"

int main (int argc, char *argv[])
{
  @autoreleasepool {
  XYPoint *myPoint = [[XYPoint alloc]init];

  [myPoint setX: 100 andY: 200];
  myRect.origin = myPoint;

  NSLog (@"Origin at (%i, %i)" , myRect.origin.x, myRect.origin.y); 

  [myPoint setX: 50 andY: 75];

  NSLog (@"Origin at (%i, %i)" , myRect.origin.x, myRect.origin.y);
}
@end

Origin at (100, 200)
Origin at (100, 200)

Upvotes: 0

Views: 48

Answers (2)

vadian
vadian

Reputation: 285150

When being declared an object instance variable is set to nil which is zero in terms of C / Objective-C.

To use an object it must be initialized. That's what the if statement checks and does

if (! origin) // alternative syntax if (origin == nil)
  origin = [[XYPoint alloc] init];

means

if the object is nil initialize it. If not skip the line.

The class directive rather than the import statement is used when only the type of the class is mentioned in the code and the header file is not needed. In your code the import statement is required if the classes are written in separate files.

PS: There are some lowercase / uppercase typos in your code and a semicolon is missing.

Upvotes: 0

Wain
Wain

Reputation: 119031

Defining an instance variable creates a pointer that can be used to reference an instance. It doesn't create an instance for you. So, initially there is no origin.

The if statement checks if the origin exists yet, and if not it creates a new one, then the code copies the values from the one passed in the parameter.

Aside: Ideally the point class would be immutable and implement copying so rather than repeatedly creating new instances and updating them you can just copy the passed parameter. Copying would do nothing (return self) in the immutable class and is there only to support the addition of a mutable class in the future.

Upvotes: 1

Related Questions