views:

292

answers:

3

I'm developing an iPhone app, and I'm kinda new to Objective-C and also the class.h and class.m structure.

Now, I have two classes that both need to have a variable of the other one's type. But it just seems impossible.

If in class1.m (or class2.m) I include class1.h, and then class2.h, I can't declare class2 variables in class1.h, if I include class2.h and then class1.h, I can't declare class1 variables in class2.h.

Hope you got my idea, because this is driving me nuts. Is it really impossible to accomplish this?

Thanks.

+9  A: 

You can use the @class keyword to forward-declare a class in the header file. This lets you use the class name to define instance variables without having to #import the header file.

Class1.h

@class Class2;

@interface Class1
{
    Class2 * class2_instance;
}
...
@end

Class2.h

@class Class1;

@interface Class2
{
    Class1 * class1_instance;
}
...
@end

Note that you will still have to #import the appropriate header file in your .m files

e.James
+1 In fact, some people strongly recommend ONLY doing it this way within your own code. Since you generally only need the class type name in the header (for variables, parameters, and return types) this tends to simplify your import chain, and makes all the header files faster to process. Definitely see the SO link @teabot provided just below the question as well.
Quinn Taylor
@Quinn Taylor: good point. I hardly ever use `#import` in my own header files, unless it is required for inheritance.
e.James
Thanks. But it doesn't seem to work all the way. I get this message when I use it. "warning: receiver "Class2" is a forward class and corresponding @interface may not exist". And when I try to access one of it's components, it errors out that that component does not exist. By appropriate header you mean it's own header? or both of them?
treznik
@skidding: Yes, each source file will have to include *both* headers in order to prevent that warning.
e.James
Hmm, nevermind, I just read the SO page from teabot's link and I think I've got it.
treznik
+1  A: 

A circular dependency is often an indication of a design problem. Probably one or both of the classes have too many responsibilities. A refactoring that can emerge from a circular dependency is moving the interdependent functionality into its own class that the two original classes both consume.

Can you describe the functionality that each class requires from the other?

Aidan Ryan
Well. Basically Class1 creates an instance of Class2, which fires a script that loads an external image asynchronously, and when the images is loaded a method from Class2 is fired, which must fire a method from Class1. You may wonder then why do I need Class2 after all, where there are some added functionalities besides the image load so I need it. Hmm, I just realized, can I store the Class1 references as an <id> type?
treznik
Sounds like a job for a delegate or event. Class2 does not need to know that Class1 in particular cares about the image load completion, just that there are others out there that want to know about it. Class2 should expose an event/notification that it fires when image load is complete. The consumers are responsible for subscribing and choosing what to do when the notification occurs.
Aidan Ryan
Here are many ways to implement loosely-coupled communication between objects: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html
Aidan Ryan
A: 

@class Class2;

@interface Class1 { Class2 * class2_instance; } ... @end

Class2 * class2_instance; // here u created a new instance variable to class2. but i need the current value of a variable that defined in Class2.. how to get the current value of the variable defined in Class2 .

srinivas