Laurent Crivello
Laurent Crivello

Reputation: 3931

Accessing objects of parent class in cocoa

I have a main AppDelegate class (MacOS development, not iOS) initiating a child class with

myChildClassObject=[[myChildClass alloc]init:self];

So I do send the parent reference to the child class. However how can I access an object of my parent class from my child class ? I tried with

parent.myObject

but it doesn't find it.

My parent class is defined like this:

@interface AppDelegate : NSObject <NSApplicationDelegate>
{
    NSView *myObject;
}

@property (nonatomic, readwrite, retain) NSView *myObject;
@end

My child class is defined like this:

@interface Gfx
{
}

Thanks.

Upvotes: 0

Views: 477

Answers (2)

CRD
CRD

Reputation: 53000

First I assume your child class is defined as:

@interface Gfx : NSObject

(The NSObject is omitted in the question, you also call it both Gfx and myChildClass) I.e. your "child" is not a subclass of your "parent".

You have not given the declaration of the Gfx init method, so we guess:

- (id) init:(id)parent

Now the "dot" syntax for accessing properties relies on the static type of the variable holding the object reference and not the actual type of the reference object. So if you have:

id parent; // instance variable

and

parent.myObject

then the compiler will object as id does not have a property myObject. Two solutions:

(a) call the setter/getter methods directly, e.g.:

[parent myObject];      // get the value of the property
[parent setMyObject:e]; // set the value of the property to e

This works as the compiler treats id specially and performs no static type checking on calls, the methods are found dynamically at runtime only. However this also raises a problem, what if the object referenced by parent does not have a myObject/setMyObject method? You will get an error at runtime.

(b) Type or cast parent correctly. To type you would change the instance variable and init declarations to use AppDelegate, e.g.:

- (id) init:(AppDelegate *)parent

This will give you static (compile time) type checking and dot notation. You can also use a cast, leaving parent as id you can use:

((AppDelegate *)parent).myObject; // compiler will be happy

However this does not check that parent is does reference an AppDelegate object - a cast is a "trust me" instruction to the compiler. So using casts bypasses static type checking, but runtime checks are still performed.

HTH

Upvotes: 1

Michael Dautermann
Michael Dautermann

Reputation: 89509

There's a couple things here:

1) You can easily get a reference to an application's delegate via this line:

AppDelegate * appDelegate = [[NSApplication sharedApplication] delegate];

2) If you want to store a reference to the parent in the child, you can do something like this:

add a property to your child's .h @interface file that looks like this:

@property (retain) id parent;

Then, in your parent class and right after instantiating your child object, you can do:

ChildObject * child = [[ChildObject alloc] init];
child.parent = self;

And you can refer to the parent class from within the child via:

self.parent;

Upvotes: 1

Related Questions