I am new Objective C. I am trying to understand and workout problems from Stephen Kochan’s Programming in objective c 2.0. This problem is from chapter 8.
What I don’t understand is: why can’t I assign variable values directly when I can get them.
For example:
This does not give me a error or warning. But it also does not set the value of X and Y.
go.origin.x = 300;
go.origin.y = 100;
But, this works fine and gives me the intended result:
NSLog (@"print %i, %i", go.origin.x, go.origin.y);
Here is my XYPoint.h
#import <Foundation/Foundation.h>
@interface XYPoint : NSObject {
int _x;
int _y;
}
@property int x;
@property int y;
@end
XYPoint.m
#import "XYPoint.h"
@implementation XYPoint
@synthesize x = _x;
@synthesize y = _y;
@end
GraphicObject.h
#import <Foundation/Foundation.h>
#import "XYPoint.h"
@interface GraphicObject : NSObject {
XYPoint *_origin;
}
@property (nonatomic, retain) XYPoint *origin;
-(void) setOrigin : (XYPoint *) pt;
@end
GraphicObject.m
#import "GraphicObject.h"
@implementation GraphicObject
@synthesize origin = _origin;
-(void) setOrigin : (XYPoint *) pt {
_origin = [[XYPoint alloc] init];
_origin = pt;
//_origin.x = pt.x;
//_origin.y = pt.y;
}
@end
Also if don’t want my origin.x and origin.y to be changed when I change my xypoint x and y, why do I have to do this:
_origin.x = pt.x;
_origin.y = pt.y;
and why not just:
_origin = pt;
For example in the main file:
XYPoint *myPoint = [[XYPoint alloc] init];
go.origin = myPoint;
myPoint.x = 250;
myPoint.y = 50;
NSLog(@"Origin values %i, %i", go.origin.x, go.origin.y);
myPoint.x = 100;
myPoint.y = 10;
NSLog(@"Origin values %i, %i", go.origin.x, go.origin.y);
I understand that the values of origin don’t change. But do I have to, in the setOrigin: method, assign it in this way:
_origin.x = pt.x
and not like this:
_origin = pt;
Thanks everyone. I know this is a long question. I really tried to understand and also looked in many places but I don’t even know what to search for. What do you call this kind of assignment?
Congrats! You’ve discovered that Objective-C properties are syntactic sugar around a getter method and a setter method. Because a property is not truly a field of an object (as
xandyare fields of aCGPointstructure), modifying fields of the object’s properties does nothing–the code is resolved to mean “get the value of the property, then modify the resultant copy of that value.”Now, you can chain property gets and sets (e.g.
anObject.widget.gear.speed *= 2) and you can chain field gets and sets (e.g.myStructure.owner.uniqueID = rand()) and, as you can see, they look pretty much identical. But you can’t mix and match them.Why?
Well, because… you can’t. And that’s pretty much it. So, in the future, if you’re having these sorts of problems, check to see if you’re mixing and matching properties and fields. If so, you’ll have to break it apart: