Reputation: 11493
So when I'm typing the name of the class, cue
, it shows up in XCode as a suggestion for what to write and when I'm importing the header the same thing happens (XCode suggests the header I'm importing as I type) so the file address is definitely right. Yet it gives me an error that the type I typed does not exist, or in methods it tells me that I need a type name.
Class interface:
#import <Foundation/Foundation.h>
#import "CueTableCell.h"
#import "CueList.h"
typedef enum {
none,
immediate,
after,
afterWait,
} CueType;
@interface Cue : NSObject
@property CueType cueType;
@property NSString* title;
@property float wait;
@property (strong, nonatomic) Cue* nextCue;
@property CueTableCell* cell;
@property CueList* list;
-(id) initWithTitle: (NSString*) title cueType: (CueType) type list: (CueList*) list cell: (CueTableCell*) cell wait: (float) wait thenCall: (Cue*) nextCue ;
-(void) fire; //Should not be async.
-(void) reset; //Pauses and resets everything
-(void) callNext;
-(void) selected;
-(void) select;
@end
CueTableCell file that will not recognize the Cue.h file:
#import "Cue.h"
@interface CueTableCell : UITableViewCell
-(void) updateBarAt: (float) playHead;
-(void) updateBarIncrease: (float) by;
- (void)setTitle:(NSString *)title wait: (float) wait fadeOut: (float) fadeOut fadeIn: (float) fadeIn playFor: (float) playFor;
@property (nonatomic, weak) IBOutlet UILabel* titleLabel;
@property (nonatomic, weak) IBOutlet UILabel* waitLabel;
@property (nonatomic, weak) IBOutlet UILabel* fadeInLabel;
@property (nonatomic, weak) IBOutlet UILabel* fadeOutLabel;
@property (nonatomic, weak) IBOutlet UILabel* playForLabel;
@property (nonatomic, strong) NSString* title;
@property (nonatomic) float wait;
@property (nonatomic) float fadeIn;
@property (nonatomic) float fadeOut;
@property (nonatomic) float playFor;
@property (nonatomic, weak) Cue* cue; # <---- Get an error that Cue is not a type
@end
For some reason, the compiler recognizes Cue importing CueTableCell, but not the other way around. Cue is at the top of a class hierarchy, so other files clearly are able to import it. I've tried changing the group and file location of CueTableCell, and nothing helps.
Upvotes: 0
Views: 330
Reputation: 365707
#import
just does textual substitution. So, at the time the compiler tries to compile CueTableCell
, Cue
hasn't been defined yet.
If you just #import "Cue.h"
, it does an #import "CueTableCell.h"
before defining Cue
anywhere. If you directly #import "CueTableCell.h"
yourself, Cue
isn't defined anywhere. Either way, you can't use it; the compiler has no idea that it's supposed to be the name of an ObjC type. (It could just as easily be all kinds of things—even a global-variable int.)
If you get rid of that #import
at the top of Cue.h
, and instead do a #import "Cue.h"
in CueTableCell.h
, that will solve this problem… but immediately create a new, equivalent one, because as soon as the compiler gets to @property CueTableCell* cell;
it will complain that CueTableCell
isn't a type.
This is what forward declarations are for. Just add a @class Cue;
to CueTableCell.h
, and the compiler will know that Cue
is an ObjC class (which is all it needs to know at this point).
You can probably also just add @class CueTableCell;
to Cue.h
, and remove the #import "CueTableCell.h"
there, and likely the same for CueList
as well. Of course the .m files will probably need to include all of the headers, but that's fine; they don't have to import each other, so there's no danger of circularity.
The only reason you really need to put a #import "Foo.h"
into a header file Bar.h
is if anyone who wants to use Bar
will also need to use Foo
, and couldn't be expected to know that and add a #import "Foo.h"
into his .m file.
Upvotes: 2