What's the difference between #import and @class, and when should I use one over the other?

后端 未结 3 399
花落未央
花落未央 2020-12-04 14:27

I\'ve been teaching myself Objective-C over the past month or so (I\'m a Java head) and I\'ve got my brain wrapped around most of it now. One thing that\'s confusing me at t

相关标签:
3条回答
  • 2020-12-04 15:15

    #import brings the entire header file in question into the current file; any files that THAT file #imports are also included. @class, on the other hand (when used on a line by itself with some class names), just tells the compiler "Hey, you're going to see a new token soon; it's a class, so treat it that way).

    This is very useful when you've got the potential for 'circular includes'; ie, Object1.h makes reference to Object2, and Object2.h makes reference to Object1. If you #importboth files into the other, the compiler can get confused as it tries to #import Object1.h, looks in it and sees Object2.h; it tries to #import Object2.h, and sees Object1.h, etc.

    If, on the other hand, each of those files has @class Object1; or @class Object2;, then there's no circular reference. Just be sure to actually #import the required headers into your implementation (.m) files.

    0 讨论(0)
  • 2020-12-04 15:15

    @class is called a forward declaration. You're basically telling the compiler that the class exists but not anything about the class. Thus, it doesn't know stuff like its superclass and what methods it declares.

    As a general rule, use @class in the .h and #import in the .m, if at all possible. Like Louis said, it'll help speed up compile times. There are times when you need to #import a class in the header, though. Cases I can think of right now are:

    • You are subclassing another class
    • You are implementing a protocol

    In these cases, you must #import the header file where the class or protocol is declared because the compiler needs to know the full class hierarchy of its parent classes and implementing protocols.

    FWIW, you can forward declare protocols, too, so long as your not implementing them:

    @protocol SomeProtocol;
    
    @interface ...
    
    - (id<SomeProtocol>)someMethod;
    
    @end
    
    0 讨论(0)
  • 2020-12-04 15:26

    The other thing you want to keep in mind is that #imports slow down your compile times, since it means the the compiler needs to pull and work through a lot more header files. This is mostly masked by the use of precompiled headers, but I have occasionally been handed projects that corss imported every header instead of using @class where appropriate, and fixing them can improve compile time. It is subtle way the the system reinforces the fact that if you only use what you actually need things go faster.

    As a general rule, I always use @class declarations in in my header files, and only #import the superclass. That falls in line with Ben's suggestions, but I thought it was worth noting that even if you are not worried about circular refs it is good idea to limit #imports in header files if you can.

    0 讨论(0)
提交回复
热议问题