3

In order to keep my build times down and also to keep my code as succinct as possible, I've been using forward-declarations in my header files and placing my #import statements in my implementation files. This has been working great so far, however I've come across a problem. Suppose I have a class MyClass that returns an object of class Widget, such as:

@interface MyClass : NSObject
-(Widget*)widgetWithName:(NSString*)name;
@end

Assume Widget has a method -(void)arbitraryMethod;

Now, suppose I am implementing a class that imports MyClass.h, instantiates a MyClass object, performs widgetWithName:, and then tries to send the arbitraryMethod message to the returned Widget, I get the error receiver type "Widget" for instance message is a forward declaration. So, I have to go ahead and import the Widget.h header file to fix the error.

Of course, this is never a problem when I'm returning Foundation classes because #import <Foundation/Foundation.h> is in Prefix.pch.

What is the best practice? My gut feeling is that if I'm returning a class or using that class as an argument in a public method, the header file should be included in my header file. Otherwise, if I had a class that used ten different non-foundation classes in public facing methods, my users would have to hunt down and import a new header file into their project every time they wanted to use that method.

Is this correct or is there a better pattern to use?

Stephen Melvin
  • 3,696
  • 2
  • 27
  • 40

2 Answers2

3

You can't skip importing headers in your header to the point where you aren't importing ones for classes you're using in your return types. I'm assuming you'd use @class Widget; in MyClass's header in this kind of circumstance. You cannot call a method on an object whose type is solely forward declared with @class because, as I remember bbum saying, the compiler does not have the necessary data. You've basically told it nothing of the class except that "it exists" through the use of @class, which isn't generally used for more than breaking circular references. I think as clean as you can get it is importing headers for classes you use internally in your implementation but, as you said, importing the headers of any classes used as return and argument types in public methods in your header.

Community
  • 1
  • 1
Metabble
  • 11,773
  • 1
  • 16
  • 29
0

You are doing everything right.

Yes, you need to import both MyClass.h and Widget.h in your other class implementation file. You need to import Widget.h because you are actually using the Widget class -- by calling a method on an object pointer of type Widget *. In an implementation file you should import the header for each class that is actually used; you should never have to care about what headers MyClass.h imports or does not import (it should import as little as possible, as you are doing).

user102008
  • 30,736
  • 10
  • 83
  • 104