tags:

views:

152

answers:

3

I'm really hesitant to ask this question, since it's sure to have such a terribly easy answer, but I just can't figure it out. Here goes:

I have this Objective-C code in a file called Copier.h:

#import <Cocoa/Cocoa.h>
#import "CopyQueue.h";


@interface Copier : NSObject {
    IBOutlet NSTextField *statusField;
    IBOutlet NSTextField *toField;
    CopyQueue *queue;
}
- (IBAction)startCopy:(id)sender;
- (void)dropFile:(NSString *)theFileName;
@end

And whenever I try to compile my project in Xcode, I get a syntax error in the line where it says CopyQueue *queue; What am I doing wrong?

The file compiles when I change the line to id *queue;, but that can't be the solution, can it? Replacing all typed references with generic ones?

+1  A: 

Try...

@class CopyQueue  

@interface {
     ...
}

...

@end
David McGraw
Awesome! You're the best :) Don't know how I could have missed that.
winsmith
+1  A: 

Predeclaring CopyQueue shouldn't be necessary (the "@class CopyQueue" that David McGraw posted) as the poster has already written the line "#import "CopyQueue.h";". Perhaps the unnecessary ";" after "#import "CopyQueue" is causing problems?

In any event, make sure that the CopyQueue is declared properly in the CopyQueue.h file (with the same spelling and case).

Lyndsey Ferguson
CopyQueue.h is, as far as I can tell, correct. Removing the semicolon after #import "CopyQueue.h" changes nothing however. Does CopyQueue.h have to contain the @class CopyQueue statement?
winsmith
A: 

This is not a silly question at all. It reflects one of the more complicated aspects of using a statically typed, compiled language like C (and Objective-C which is a C superset). For folks coming from dynamically typed languages (like Python, Ruby, PHP etc.), this can be slightly bumpy transition.

Before you can use a type (in C, Objective-C or C++), you must declare that type. CopyQueue is a type, so it must be declared (using @interface CopyQueue : SomeClass {} @end or implicitly declared using @class CopyQueue. In the example you posted, a Cocoa programmer would assume that CopyQueue.h contains something like this

@interface CopyQueue : SuperClass { //where SuperClass is the name of the class that CopyQueue inherits from

  ...
  }
...
@end

If this is not the case (your comment to Lyndsey Ferguson suggests that it is not), you must include the header file that defines the CopyQueue class type (as above), or tell the compiler that CopyQueue is a class (using @class CopyQueue).

The @class CopyQueue declaration is a way of telling the compiler that it can treat CopyQueue* as a pointer to an Objective-C class (type id) and that you'll fill in the details (such as CopyQueue's instance variables and methods) via an @interface later on (such as in a separate module).

Barry Wark
Have a look at the source at http://bitbucket.org/winsmith/copymeister/src/ . The definition of CopyQueue is included in the file, yet I still need the @class-line to make it work. (which is okay for me btw)
winsmith
You have a circular reference: Copier.h imports CopyQueue.h which imports Copier.h. In this case, you are correct: you need to use the forward @class declaration. You can remove the #import CopyQueue.h from the header with the @class CopyQueue line.
Barry Wark