浅论@class与#import

作者: Z_Aaron | 来源:发表于2017-03-06 22:27 被阅读0次


    一、#import和#include的区别

    1.#include相信我们学C/C++时候是引入头文件用习惯了#include,但是#include的最大缺点就是引用的文件可以被多次引用),这样就陷入了递归包含。

    比如:class文件A、B都引用了class C,如果class D引用了class A、B,这时候编译通过,链接就会报重复引用的错误,因为相当于class D引用了两次class C

    2.#import:为了解决递归包含问题,优化的#include。确保了引用的文件只会被引用一次。


    二、@class的引入(又叫”向前声明“)

    1.什么是@class:

    @class不像#import那样链入该头文件的全部信息(包括实例变量和方法等)而是让别人只需要知道它是个类名,不需要知道细节

    2.为什么要引入@class:

    (1)解决相互依赖(相互包含)问题。

    当即系其中一个头文件是编译器发现他引入了另一个头文件,而那个头文件有引用了第一个头文件,如果用#include会导致死循环,用#import会意味着其中一个类无法正确被编译。

    例:

    //  Man.h

    #import<Foundation/Foundation.h>

    // import会链入该头文件的全部信息 ,包括实例变量和方法等

    #import "Women.h"

    //只告诉编译器Women是类名称,不需要知道实例变量和方法等

    //@class  Women;

    @interface Man : NSObject{

    @public

    Women *_women;

    }

    -(void)love;

    @end

    //  Man.m

    #import "Man.h"

    #import "Women.h"

    @implementation Man

    -(void)love{

    [_women walk];

    }

    @end

    //  Woman.h

    #import<Foundation/Foundation.h>

    #import "Man.h"

    @interface Women : NSObject{

    Women *_women;

    }

    -(void)walk;

    @end

    //  Woman.m

    #import "Women.h"

    @implementation Women

    - (void)walk{

    NSLog(@"walk together");

    }

    @end

    main.m

    #import<Foundation/Foundation.h>

    #import "Women.h"

    #import "Man.h"

    int main(int argc, const char * argv[]) {

    @autoreleasepool {

    //Women.h和Man.h相互导入会出现问题

    //这时候我们就可以使用@class解决这样的问题

    //我们一般在.h文件中使用@class,因为在.h文件中一般是不会使用类的属性和方法的

    //在.m文件中可以导入.h文件

    Man *man =[[Man alloc] init];

    Women *women = [[Women alloc] init];

    man->_women= women;

    [man love];

    }

    return 0;

    }

    如果这时候run会报错,我们可以看一下报错内容(Xcode Version 8.2.1)。

    报错

    报错是未知的类型名称Woman,不过我们明明都有,再仔细看一下报错内容是文件既包括在Women中,又包括在main中。

    //如果我们把Man.h中的代码改成向前声明就OK了

    #import<Foundation/Foundation.h>

    //#import "Women.h"

    @class  Women;

    @interface Man : NSObject{

    @public

    Women *_women;

    }

    -(void)love;

    @end

    (2)对于编译效率而言

    假设有500个文件都#import了同一个头文件或依次引用(a->b,b->c,c->d.....),如果最开始的那个头文件有变化(例如a)那么所有后边的所有引用的类都需要重新编译,这样就会耗费大量时间,用@class则不会。

    (3)一般来说@class是放在interface中的,只是为了在interface中引用这个类,把这个类作为一个类型来用,在实现这个接口的类中,如果需要引用这个类的实体变量或者方法之类的,还是需要@import在@class中声明的类来0。

    (4)可以尽量降低类之间的耦合

    相关文章

      网友评论

        本文标题:浅论@class与#import

        本文链接:https://www.haomeiwen.com/subject/nklrgttx.html