2

I know that there are many questions on stackoverflow about the differences between @class forward declarations and #imports - and I do understand that it is mostly compiler optimization and reducing circular import problems.

My question is more about coding style in the following circumstances, say for instance I have a model structure like below.

// Classroom.h
@class Teacher;

@interface ClassRoom : NSObject

@property (nonatomic, strong) Teacher *teacher;
- (NSArray *)students;

@end



// Teacher.h
@interface Teacher : NSObject

@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;

@end

Now, when I am using this in another class I would need to import both Teacher.h and ClassRoom.h if I wanted to access the firstName property via

teacherObject.firstName

Whereas if I used #import Teacher.h instead of @class Teacher; I would only have to import #Teacher.

So my main question is if this is a reasonable occasion to use an import instead of a forward declaration? The actual model structure I am using in my project is much more complex than this and I often have to import 5-10 different model classes at the beginning of my implementation files (in the controllers). While this does not hurt anything it does become frustrating and make the source code longer. I would love to hear opinions on this from Objective-C veterans.

Lee Duhem
  • 14,695
  • 3
  • 29
  • 47
xizor
  • 1,554
  • 2
  • 16
  • 35
  • possible duplicate of [@class vs. #import](http://stackoverflow.com/questions/322597/class-vs-import) – Avt Mar 07 '14 at 22:59
  • @Avt thank you for the link. I did find that question (and many more) while searching StackOverflow.com but it is not exactly what I am asking. I am more curious if it is good practice to use #imports in a deep model hierarchy to prevent tens of lines of imports in all of the controller classes that use the model. Thank you. – xizor Mar 08 '14 at 17:00

3 Answers3

2

I always do it like apple does: I 'never' cascade imports but I usually have a 'wrapper h file' ...

like when I have FeatFooA.h FeatFooB.h FeatFooC.h
I also have a AllFeaturesFoo.h

Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
  • an umbrella header so to speak – Daij-Djan Mar 05 '14 at 14:30
  • I *think*, but can't find the video to back me up, that making these precompiled headers (.pch) would also give a performance increase at compile time. – James Webster Mar 05 '14 at 14:35
  • those wouldnt be pchs at all. You shouldnt only rely on pchs. Although they increase performance and it might make sense to add those to the pch later – Daij-Djan Mar 05 '14 at 14:52
  • pchs do increase performance but make the whole thing more fragile. google the benefits/drawbacks of pchs for that – Daij-Djan Mar 05 '14 at 14:53
1

I personally find it nice/handy to explicitly show dependencies with #imports in .m files.

However, files that are generic for the app, and could be used in (almost) all modules, form an exception.

  1. In such case you could use one common header where you #import all those generic headers; and then #import this single header in every module.

  2. Alternatively you could put this list of generic #imports in your AppName-Prefix.pch file. (Or even do one #import of a common header (see above).) In that case you don't have to #import anything in your modules. But I personally don't like hidden/implicit stuff; so I'd rather choose the first option.

Then with regards to your example: It may make sense to create a School.h, which would then be the only header that's needed. If things are dependent on each other, because it's all part of a certain concept ('school' in this example), it's good to keep the interface simple. I know this sounds vague, but I hope you get the point.

meaning-matters
  • 21,929
  • 10
  • 82
  • 142
0

As I understand your question is about code quality and best coding practices.

IMHO #import is more convenient since you will never receive a compiler error "Unknown Class".

BUT there is one case where I will not recommend to use #import. Assume you have several layers in your app. Lets say: Network, Controller and View (GUI). For some reasons you have to access GUI class MyProgressView from Network layer (for example you are using third-party lib):

@interface MyNetworkClass : NSObject
@property (strong, nonatomic) MyProgressView *progressView;
@end

If you will use #import any Network-layer class that imports MyNetworkClass.h will also know about MyProgressView. It is contrary to responsibility sharing! So in this case @class will be better.

Avt
  • 16,927
  • 4
  • 52
  • 72