Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

gilpster

macrumors newbie
Original poster
Feb 25, 2011
4
0
Hi Everyone,

I've quite a bit of experience coding in Java etc. I'm trying to port a program from Java to Objective C but i'm struggling with one aspect:

I have a main class called 'Body' which creates instances of many other classes. Lots of theses classes inherit from a few parents classes. They all need to reference to each other, and in particular back to the 'Body' class (to which most of them belong)

In Java I passed a refence to the class in the constructor:

Code:
Dog dog = new Dog(this);

which was then stored as a pointer to the main Body class in the new class:

Code:
private Body body;

public Dog(Body bodyRef)  {
     body = bodyRef;
     //now do things with this refence throughout the class
     body.doCoolThings();
}

And these pointers were inherited throught my OOP so I could refence this 'Body' class anywhere.

I've tried doing the same thing with Objective C and I can't. I know i've probably got some deep misunderstanding here, but if you do this:

Code:
Body bodyRef = [[Body alloc] init];
Body body = bodyRef;

Would this just create two pointers to the same object in ObjC?

I can't even seem to:

#import "Body.h"

In the interface of the other class files as it gives me an error when I compile - although I can import all my other classes.

So how do you pass a pointer of a class to a another class in ObjC?

Many Thanks

Kenneth
 
Last edited:

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
In Objective-C you run into problems when class A imports class B and class B imports class A. I imagine this is what you're seeing. To solve it you need to use @class.

For example, the wrong way:
Code:
[color=#007400]// A.h[/color]
[color=#643820]#import [/color][color=#c41a16]"B.h"[/color][color=#643820]
[/color][color=#aa0d91]@interface[/color] A : NSObject {
    [color=#3f6e74]B[/color] *[color=#3f6e74]b[/color];
}
[color=#aa0d91]@end
[/color]
[color=#007400]// B.h[/color]
[color=#643820]#import [/color][color=#c41a16]"A.h"[/color][color=#643820]
[/color][color=#aa0d91]@interface[/color] B : NSObject {
    [color=#3f6e74]A[/color] *[color=#3f6e74]a[/color];
}
[color=#aa0d91]@end[/color]

The right way:
Code:
[color=#007400]// A.h[/color]
[color=#aa0d91]@class[/color] [color=#3f6e74]B[/color];
[color=#aa0d91]@interface[/color] A : NSObject {
    [color=#3f6e74]B[/color] *[color=#3f6e74]b[/color];
}
[color=#aa0d91]@end[/color]
[color=#007400]
// B.h[/color]
[color=#aa0d91]@class[/color] [color=#3f6e74]A[/color];
[color=#aa0d91]@interface[/color] B : NSObject {
    [color=#3f6e74]A[/color] *[color=#3f6e74]a[/color];
}
[color=#aa0d91]@end[/color]

Then in the implementation (.m) file, you can #import the class.

@class basically just tells the compiler that this class name exists. It doesn't need to know anymore about it at that point.

You should almost always use this, except when subclassing another object or conforming your object to a protocol.
 
Last edited:

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Not sure if Body is an instance and the other objects are instantiated in instance methods, or if the other Objects are instantiated from a static/class method. If you need to pass the class, there is a Class type and you can get this by passing the message class to an object (including a class object). If you're dealing with an instance you can pass self to an init method.

Class:
Code:
From body.m:

Dog *myDog = [[Dog alloc] initWithParentClass:[Body class]];

From Dog.h:
...
Class parentClass;
...


From Dog.m:

(id) initWithParentClass: (Class) inClass {
  ...
  parentClass = inClass;
}

Using an instance:
Code:
From body.m:

Dog *myDog = [[Dog alloc] initWithBody: self];

From Dog.h:

body *bodyRef;

@property (retain) body *bodyRef;

From Dog.m:

(id) initWithBody: (body *) inBody {
  ...
  [self setBodyRef:inBody];
  ...
}

Hopefully one of these is what your looking for, and the very short examples help. If not, post again.

-Lee
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
In Objective-C, you can send messages to classes and to objects. For example:

Code:
NSArray* anArray = [[NSArray alloc] init];
int count = [anArray count];

sends the alloc message to class NSArray, which returns an object, then sends the init message to that object, and the count message to the object returned. To get a class object, send the "class" method:

Code:
Class someClass = [NSArray class];
NSArray* anArray = [[someClass alloc] init]

will do exactly the same thing.
 

gilpster

macrumors newbie
Original poster
Feb 25, 2011
4
0
Thanks guys - your answers have sorted this problem out for me I think:

@lee1210, gnasher - I wanted to pass an instance of the class rather than the class itself.

@kainjow - using the

Code:
@class foo;

in the interface solved the problem. I think you hit the nail on the head. A better way to define my problem would be if you had three classes, A, B and C. Supposing an instance of A creates instances of classes B and C. Then what would you do if you wanted to access the instance of class C from class B? I think you'd do it this way:

Code:
// B.h
@class A;
@interface B : NSObject {
    A *a;
}
@property(nonatomic, retain) A * a;
-(void) getReferenceFromA: (A *)aRef;
-(void) usingCfunction;
@end

// B.m
#import "A.h"
@implementation B
@synthetize a;

-(void) getReferenceFromA: (A *)aRef  {
    a = aRef;
}

-(void) usingCfuntion {
   [a.c setSomething];  //assuming that the instance of C is 'c'
}
@end

if this is right - and it seems to work in Xcode here - i'll mark the thread solved - (but I don't know how)

kenneth
 

elppa

macrumors 68040
Nov 26, 2003
3,233
151
if this is right - and it seems to work in Xcode here - i'll mark the thread solved - (but I don't know how)

kenneth

Just edit the title and put [solved] at the front. That should do. There is no formal way.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.