Reputation: 1532
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
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
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:
Upvotes: 0