views:

67

answers:

2

I am working on a project with several custom classes. I have a CardModel (NSObject) that has some integer properties to hold data, and a Deck (NSObject) that has an array to hold a bunch of CardModels and then a CardView (UIView) that has a CardModel as a property that I make when I select a CardModel from a Deck. And then I've got a bunch of UIViewControllers that I move around on a UINavigationController.

My question is about where and when to use the @class compiler directive.

If I subclass a UIViewController by making a new file and subclassing it, should I use the @class MyViewController in the header of MyViewController.h or .m and does it go in the header of the file that actually uses the controller (like when one controller is going to instantiate another controller type and push it to the stack). Or do I need to use it at all? Is it only required if I actually add new properties to my class beyond what's in the stock implementation? It seems like I'm putting @class all over the place just make sure I don't get errors but I don't fundamentally understand when I need it.

Thanks!

+3  A: 

The @class directive is used when you need a header to know about a class but you don't want to import the class's header file; e.g., when you need to avoid circular dependencies.

Wevah
+4  A: 

You use it in the .h to inform it about a custom class without including the .h for the custom class.

Example: Two custom classes: Car and Wheel

Car.h
----------------
@interface Car : NSObject {
}
- (void)addWheel:(Wheel*)newWheel;
@end

Car.h doesn't know about the class 'Wheel' so it would throw an error so you could import the Wheel.h like so:

Car.h
----------------
#import "Wheel.h"

@interface Car : NSObject {
}
- (void)addWheel:(Wheel*)newWheel;
@end

BUT you dont need to do this either. Car.h doesn't need to know anything about the Wheel class, it just needs to know it exists. So what you use is the @class to just say that "Hey, this class exists. Take my word for it."

Car.h
----------------
@class Wheel;

@interface Car : NSObject {
}
- (void)addWheel:(Wheel*)newWheel;
@end

Then inside of the Car.m, when you actually need to know about the Wheel class (properties, methods, etc) you should import the Wheel.h there.

ACBurk
Thanks - that seems pretty clear. @class in the header tells that header that references to that class are ok. Then an #import of the .h file in the corresponding .m file gives the implementation access to all of the actual properties and methods of the class. But is this only true for things that are subclassed from NSObject, or all superclasses? Would it be correct to say that any time I make a "new file" and choose a subclass, I'll need to follow this, and any time I just instantiate a class in my code that is a regular class, I don't?
Steve
All superclasses, too. `@class X` is simply shorthand for "there exists a class X for which there can be pointers". Nothing more, nothing less. It is only needed when you can't import the header for the class first (typically, in the PCH file).
bbum
So I may have the same `@class x` directive in multiple headers, so long as those headers need to know about `x`, either as a property or in a method they implement, right? Starting to solidify in my mind - thanks!
Steve
Simpler still; you can put `@class X;` wherever you want, whether or not you even need it. It does very little beyond enabling `X *` based declarations. It is up to you to use it sparingly.
bbum
So the PCH (precompiled header?) file has the information about all the typical objects and is why I don't need to tell the compiler about things like UIButton or UIViewController ahead of time?
Steve
If you look in the pch, there's a section that has #import <UIKit/UIKit.h>which imports the UIKit stuff which has all the standard, vanilla stuff (like UIButton and UIViewController)
ACBurk