OC学习篇之---@class关键字的做用以及#include和#import的区别 分类: IOS 2014-12-06 13:09 3920人阅读 评论(0) 收藏

前一篇文章说到了OC中类的三大特性:http://blog.csdn.net/jiangwei0910410003/article/details/41707161今天咱们来看一下在学习OC的过程当中遇到的一些问题,该如何去解决,首先来看一下咱们以前遗留的一个问题:学习


1、#import和#include的区别测试

当咱们在代码中使用两次#include的时候会报错:由于#include至关于拷贝头文件中的声明内容,因此会报重复定义的错误spa

可是使用两次#import的话,不会报错,因此他能够解决重复导入的问题,他会作一次判断,若是已经导入一次就不导入了.net


2、关键字@class的做用指针

在来看一下OC中的关键字@class的做用,在看他的做用以前,先来看一个问题:code

如今有一个课程类Classes和学生类Student,他们两之间须要相互引用(导入)。直接看代码比较直接:blog

Classes.hip

//
//  Classes.h
//  08_@class
//
//  Created by jiangwei on 14-10-11.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Student.h"

//不会将Student.h拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中任何信息(哪些属性和方法)
//@class Student;

@interface Classes : NSObject{
    
@public
    Student *_student;
}

- (void)t1;

@end

导入Student.h头文件


Classes.mget

//
//  Classes.m
//  08_@class
//
//  Created by jiangwei on 14-10-11.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import "Classes.h"

//#import "Student.h"

@implementation Classes

- (void)t1{
    [_student work];
}

@end


在来看一下Student类

Student.h编译器

//  Student.h
//  08_@class
//
//  Created by jiangwei on 14-10-11.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Classes.h"

@interface Student : NSObject{
    Classes *_classes;
}

- (void)work;

@end
一样的也导入Classes.h头文件


Student.m

//
//  Student.m
//  08_@class
//
//  Created by jiangwei on 14-10-11.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import "Student.h"

@implementation Student

- (void)work{
    NSLog(@"work");
}

@end


在来看一下测试代码:

main.m

//
//  main.m
//  08_@class
//
//  Created by jiangwei on 14-10-11.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Classes.h"
#import "Student.h"

//Classes和Student相互导入会出现问题
//这时候咱们就能够使用@class解决这样的问题
//咱们通常在.h文件中使用@class,由于在.h文件中通常是不会使用类的属性和方法的
//在.m文件中能够导入.h文件
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Classes *cls =[[Classes alloc] init];
        Student *stu = [[Student alloc] init];
        cls->_student = stu;
        [cls t1];
        
    }
    return 0;
}
这里有一个问题注意一下:咱们看到了这里是如何使用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

//
//  Classes.h
//  08_@class
//
//  Created by jiangwei on 14-10-11.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import <Foundation/Foundation.h>

//#import "Student.h"

//不会将Student.h拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中任何信息(哪些属性和方法)
@class Student;

@interface Classes : NSObject{
    
@public
    Student *_student;
}

- (void)t1;

@end
咱们将#import "Student.h"代码注释了,使用

@class Student

这段代码的做用就是不会将Student.h文件拷贝过来,只是告诉编译器Student这个类在别的地方中有定义,这样就不知道这个类中的任何信息了(哪些属性和方法)

Classes.m

//
//  Classes.m
//  08_@class
//
//  Created by jiangwei on 14-10-11.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import "Classes.h"

#import "Student.h"

@implementation Classes

- (void)t1{
    [_student work];
}

@end
而后在Classes.m文件中导入#import "Student.h"文件,这时候编译就不会报错了,一样就能够正常的运行了:



总结

这一篇文章就介绍了#import关键字和@class的做用,特别是@class关键字的使用,为了解决相互导入的问题,在此回顾一下咱们是怎么操做的:

Student类中的导入Classes.h方式不变,在Classes.h头文件中使用@class关键字引入Student类型,使其编译经过,而后在Classes.m文件中导入Student.h文件,使其运行经过。

之后遇到这样的问题解决方法就是这样操做的。

相关文章
相关标签/搜索