sinθ
sinθ

Reputation: 11493

Compiler not recognizing class existence, even after importing header

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

Answers (1)

abarnert
abarnert

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

Related Questions