pls
pls

Reputation: 1532

Subclassing view controller: Forward declaration

I have been following the rule of having:

@MyClassName in the header file of a class

&&

#import "MyClassName" in the implementation

I have now decided to subclass one of my view controllers. If I overwrite a method then I get the following message:

Receiver 'MyClassName' for class message is a forward declaration

To over come this I need to put the #import into the header file which doesn't seem to follow what I thought was best practices.

Can someone explain if I have misunderstood the use of @class?

Or if I am dong things correctly, can someone please explain you need to break best practices and use #import in header file when subclassing?

Many thanks.

Edit:

Thanks for the answers. I think I need to add some more detail to clarify my situation and hopefully my understanding. Here is my header for my base class:

#import <UIKit/UIKit.h>
#import "CorePlot-CocoaTouch.h"

@class Organisation;

@interface LongCallDetailViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

In my impementation I have

#import "Organisation.h"

My subclass header contains the following:

#import "LongCallDetailViewController.h"

@interface LongCallSubclassViewController : LongCallDetailViewController

@end

If I override a method in the subclass and try to use an Organisation object it gives me the error as I stated above. Therefore I either need to add #import "Organisation.h" into the base classes header or duplicate the #import "Organisation.h" into the subclasses implementation file. Both of which seem wrong to me.

Many thanks.

Upvotes: 3

Views: 432

Answers (2)

Ian MacDonald
Ian MacDonald

Reputation: 14010

Within header files, you should be importing other header files for any classes you subclass. You do not need to import header files for classes that are just referenced and not subclassed. For example, a header file might look like:

#import "MySuperClass.h"

@class MyObjectType;

@interface MySubClass : MySuperClass
@property (strong) MyObjectType *value;
@end

Edit: Based on your new edits, it looks like you are writing your header files correctly. When you only declare @class in a scope, you will not be able to access any of the selectors or properties associated with that class. It is okay to declare using @class in places where you are not intending to use selectors or properties of that class type and just pass around a reference (as in the header I have described above), but as soon as you want to do anything else with the object, you'll need to have imported the header file describing the @interface.

When defining a @class MyObjectType in a header file, it is generally expected that the #import "MyObjectType.h" appears in the associated source file. Header files are intended as a declaration of structure, whereas source files will contain the implementation. For example, the source file associated with the header file I described above might look like:

#import "MySubClass.h"

#import "MyObjectType.h"

@implementation MySubClass
- (void)overriddenFunction {
  [self.value anObjectTypeSelector];
}
@end

You shouldn't think about "duplicating" an import statement when they're in two different scopes. When you forward declare @class Organisation in your LongCallDetailViewController header file, you'll have a #import "Organisation.h" in your LongCallDetailViewController source file. If you also need to access this object's properties and selectors in your LongCallSubclassViewController class, you'll need to #import "Organisation.h" in your LongCallSubclassViewController implementation file. Remember: the implementation files do not know about the content of each other; they only know about the contents of the header file.

Upvotes: 3

ksysu
ksysu

Reputation: 311

#import imports definition of class with all public methods and properties.

@import predeclare class, so there is no information about methods and properties

You use #import when:

  • You subclass a class - other classes importing your class need to know about all methods that class suport.
  • You implement a protocol - same reason as above.

Upvotes: 0

Related Questions