Properties and pointers

126 views Asked by At

In Objective-C, I can't seem to be able to make a pointer to a property. For example:

I make a Class called Car which is a SubClass of SKSpriteNode.

One of the SKSpriteNode's properties is its position (a CGPoint).

Now for my Car class, I want to create 4 new properties called wheelPosition1, wheelPosition2, wheelPosition3, wheelPosition4 (which all are CGPoints)

Each of the wheelPosition properties are related to the position property of the Car (as the position property of the car will represent the centre whilst the wheels go out 1,1 in 4 directions) like this:

enter image description here

I want the wheelPosition properties to point to the address of the position property of the car whenever retrieving or setting their values...

Xcode doesn't let me do this, because the .position property is "temporary" - So I can't do something like:

CGPoint * x = &sprite.position; 

In this example, the obvious solution would just to create a new Tyre class and create a node tree with 4 tyres... but this was only an example to illustrate my problem. This is just a generic problem I have found whilst programming - I can't get a variable to ever point to the property of another Object.

Right now I'm having to change my setter methods in the class to get around this which means that if I wanted to move the centre of the car somewhere else, it would be harder...

enter image description here

But is there another way which'll allow me to point to that property of the class?

At the request of a below comment here is the code:

@interface SomeClass : SKSpriteNode

@property CGPoint newNameForPositionProperty;

-(void) newPositionToPosition

@end



@implementation SomeClass

@synthesize newNameForPositionProperty;

-(void) newPositionToPosition {

    newNameForPositionProperty = self.position;

}
@end



@implementation GameScene

-(void)didMoveToView:(SKView *)view {


    SomeClass *newObject = [[SomeClass alloc] init];

    newObject.position = CGPointMake(100, 100 * sqrt(3.0));
    [newObject newPositionToPosition];

    NSLog(@"Original Position Property: (%f, %f)", newObject.position.x, newObject.position.y);
    NSLog(@"New Position Property: (%f, %f)", newObject.newNameForPositionProperty.x, newObject.newNameForPositionProperty.y);

    //Change Position
    NSLog(@" ");
    //

    newObject.position = CGPointMake(100, 100);

    NSLog(@"Original Position Property: (%f, %f)", newObject.position.x, newObject.position.y);
    NSLog(@"New Position Property: (%f, %f)", newObject.newNameForPositionProperty.x, newObject.newNameForPositionProperty.y);
}

@end

enter image description here

Here is an example of how the code might be applied:

@interface SomeClass : SKSpriteNode

@property double modulus, argument;

-(void) positionToModulusArgument;

@end



@implementation SomeClass

@synthesize modulus, argument;

-(void) positionToModulusArgument {

    modulus = sqrt(pow(self.position.x, 2) + pow(self.position.y, 2));

    //Realistically I would split the argument into 4 cases to represent the 4 quadrants, but as this is only an example, I will assume that the position is only in the top right quadrant.
    argument = atan(self.position.y / self.position.x);
}

@end



@implementation GameScene

-(void)didMoveToView:(SKView *)view {


    SomeClass *newObject = [[SomeClass alloc] init];

    newObject.position = CGPointMake(100, 100 * sqrt(3.0));
    [newObject positionToModulusArgument];

    NSLog(@"Cartesian Form: (%f, %f)", newObject.position.x, newObject.position.y);
    NSLog(@"Polar Form: (%f, %f)",newObject.modulus, newObject.argument);

    //Change Position
    NSLog(@" ");
    //

    newObject.position = CGPointMake(100, 100);

    NSLog(@"Cartesian Form: (%f, %f)", newObject.position.x, newObject.position.y);
    NSLog(@"Polar Form: (%f, %f)",newObject.modulus, newObject.argument);
}

@end

enter image description here

In either case, the property doesn't change when the other does.

1

There are 1 answers

9
Amin Negm-Awad On

Your approach is wrong. You do not need a pointer. Simply calculate the wheel positions from the (center) position using self.position. You need the indirection of pointers, if the property that should be use can change (not its value, but the property itself), i. e. from position to anotherPosition.

However, you do not apply the address operator to the property's ivar, but to the return value of the getter -position. Return values are temporary. If you want to have a pointer to the ivar itself, use &_position.

But as I said: Don't do this at all.