zoukankan      html  css  js  c++  java
  • #import和#include的区别 关键字@class的作用

    一、#import#include的区别
    当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误
    但是使用两次#import的话,不会报错,所以他可以解决重复导入的问题,他会做一次判断,如果已经导入一次就不导入了


    二、关键字@class的作用
    在来看一下OC中的关键字@class的作用,在看他的作用之前,先来看一个问题:
    现在有一个课程类Classes和学生类Student,他们两之间需要相互引用(导入)。直接看代码比较直接:
    Classes.h
    [objc]  view plaincopy
    1. //  
    2. //  Classes.h  
    3. //  08_@class  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. #import "Student.h"  
    12.   
    13. //不会将Student.h拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中任何信息(哪些属性和方法)  
    14. //@class Student;  
    15.   
    16. @interface Classes : NSObject{  
    17.       
    18. @public  
    19.     Student *_student;  
    20. }  
    21.   
    22. - (void)t1;  
    23.   
    24. @end  
    导入Student.h头文件



    Classes.m
    [objc]  view plaincopy
    1. //  
    2. //  Classes.m  
    3. //  08_@class  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import "Classes.h"  
    10.   
    11. //#import "Student.h"  
    12.   
    13. @implementation Classes  
    14.   
    15. - (void)t1{  
    16.     [_student work];  
    17. }  
    18.   
    19. @end  

    在来看一下Student类
    Student.h
    [objc]  view plaincopy
    1. //  Student.h  
    2. //  08_@class  
    3. //  
    4. //  Created by jiangwei on 14-10-11.  
    5. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    6. //  
    7.   
    8. #import <Foundation/Foundation.h>  
    9.   
    10. #import "Classes.h"  
    11.   
    12. @interface Student : NSObject{  
    13.     Classes *_classes;  
    14. }  
    15.   
    16. - (void)work;  
    17.   
    18. @end  
    同样的也导入Classes.h头文件


    Student.m
    [objc]  view plaincopy
    1. //  
    2. //  Student.m  
    3. //  08_@class  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import "Student.h"  
    10.   
    11. @implementation Student  
    12.   
    13. - (void)work{  
    14.     NSLog(@"work");  
    15. }  
    16.   
    17. @end  

    在来看一下测试代码:
    main.m
    [objc]  view plaincopy
    1. //  
    2. //  main.m  
    3. //  08_@class  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. #import "Classes.h"  
    12. #import "Student.h"  
    13.   
    14. //Classes和Student相互导入会出现问题  
    15. //这时候我们就可以使用@class解决这样的问题  
    16. //我们一般在.h文件中使用@class,因为在.h文件中一般是不会使用类的属性和方法的  
    17. //在.m文件中可以导入.h文件  
    18. int main(int argc, const charchar * argv[]) {  
    19.     @autoreleasepool {  
    20.         Classes *cls =[[Classes alloc] init];  
    21.         Student *stu = [[Student alloc] init];  
    22.         cls->_student = stu;  
    23.         [cls t1];  
    24.           
    25.     }  
    26.     return 0;  
    27. }  
    这里有一个问题注意一下:我们看到了这里是如何使用Classes中的属性_student的,因为在Classes类中属性_student@public的,所以可以直接使用,用的是箭头符号,和C/C++中的指针变量调用差不多。记住了,这里就说到了如何直接访问一个类中的@public修饰符的属性变量


    我们编译运行:

    看到了,编译错误,说在Student类中的Classes类找不到指定类型,这就奇怪了,我们不是导入了Classes.h文件了,为什么还是找不到类型呢?
    这就是OC中类的相互引用的问题,我们在Student.h文件中导入了Classes.h,又在Classes.h文件中导入了Student.h,OC中在相互导入的时候编译是不通过的
    这样就会导致错误。
    当然解决办法就是使用@class关键字,我们修改一下Classes类
    Classes.h
    [objc]  view plaincopy
    1. //  
    2. //  Classes.h  
    3. //  08_@class  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. //#import "Student.h"  
    12.   
    13. //不会将Student.h拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中任何信息(哪些属性和方法)  
    14. @class Student;  
    15.   
    16. @interface Classes : NSObject{  
    17.       
    18. @public  
    19.     Student *_student;  
    20. }  
    21.   
    22. - (void)t1;  
    23.   
    24. @end  
    我们将#import "Student.h"代码注释了,使用
    @class Student
    这段代码的作用就是不会将Student.h文件拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中的任何信息了(哪些属性和方法)
    Classes.m
    [objc]  view plaincopy
    1. //  
    2. //  Classes.m  
    3. //  08_@class  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import "Classes.h"  
    10.   
    11. #import "Student.h"  
    12.   
    13. @implementation Classes  
    14.   
    15. - (void)t1{  
    16.     [_student work];  
    17. }  
    18.   
    19. @end  
    然后在Classes.m文件中导入#import "Student.h"文件,这时候编译就不会报错了,同样就可以正常的运行了。
  • 相关阅读:
    Python使用阿里云镜像
    Charles抓取https请求中文乱码的处理方法
    Charles 注册码
    BAT随笔记录(1)
    NodeJS使用puppeteer进行截图
    Centos中文语言乱码解决方法
    CentOS下安装Chrome浏览器中文显示为方框
    CentOS下安装Chrome浏览器
    Jenkines邮件中添加图片
    将HTML转IMAGE
  • 原文地址:https://www.cnblogs.com/GhostKZShadow/p/5105212.html
Copyright © 2011-2022 走看看