文档章节

@class #import #include辨析·

HelloSwift
 HelloSwift
发布于 2016/08/08 16:31
字数 1154
阅读 3
收藏 0

#include
        区分 #include <x.h>与#include "x.h"的作用
        
#include <x.h>:它用于对系统自带的头文件的引用,编译器会在系统文件目录下去查找该文件.
         #include "x.h":用户自定义的文件用双引号引用,编译器首先会在用户目录下查找,然后到安装目录中查找,最后在系统文件中查找。

         在使用#include的时候要注意处理重复引用(这也是objc中#include与#import的区别)

        例如:ClassA 与 ClassB同时引用了ClassC,不做重复引用处理的时候在ClassB中同时引用ClassA,ClassB编译会提示对ClassC重复引用的错误.

         我们可以在ClassC中:#ifndef _CLASSC_H

                       #define _CLASSC_H
                       #include "ClassC"
                       #endif

         这样处理在编译时就不会有重复引用的错误出现(在objc中#import解决了这个问题,这是它们的区别)

#import

         #import 大部分功能和#include是一样的,但是他处理了重复引用的问题,我们在引用文件的时候不用再去自己进行重复引用处理.

@class
        主要是用于声明一个类,告诉编译器它后面的名字是一个类的名字,而这个类的定义实现是暂时不用知道的,后面会告诉你.也是因为在@class仅仅只是声明一个类,所以在后面的实现文件里面是需要去#import这个类,这时候才包含了这个被引用的类的所有信息。
 

综上所述#include,#import与@class的区别可以做一下理解

 

         #include与#import在引用一个类的时候会包含这个类的所有信息包括变量方法等,但是这样做会对编译效率造成影响.比如有99个类都#import了ClassA,那么在编译的时候这99个类都会去对ClassA处理.又比如A被B引用,B被C引用,C被D引用.....此时如果A被修改,那么后面的B,C,D.....都需要重新进行编译.还有一个用法会引起编译错误的就是在ClassA中#import ClassB 在ClassB中#import ClassA那么在编译的时候也会出现未知错误。

        所以一般来说,在interface中引用一个类,就用@class,它会把这个类作为一个类型来使用,而在实现这个interface的文件中,如果需要引用这个类的实体变量或者方法之类的,还是需要import这个在@class中声明的类。

即:.h文件用@class来声明,.m中如果需要引用这个类的实体变量或者方法之类的,就import

1. import会包含这个类的所有信息,包括实体变量和方法,而@class只告诉编译器,声明的类的名称,至于这些类是如何定义的,暂时不用考虑,所以在头文件中如果用@class声明某个类后,在.m的实现中如果用到声明类的具体方法或变量时还得再#import类  。

 2.在.h头文件中进行声明时用#import的话,如果100个头文件都#import同一个头件,或者这些文件是依次引用的,如A->B,B->C,C->D,当最开始的那个头文件有变化后进行编译时,后面所有引用它的类都需要重新编译,如果引用最开始的头文件的类很多的话,那么这将耗费大量的时间,而用@class则不会,可能有人会想即然.h只是用@class只是简单的一个声明告编译器有这个类不让其报错,那么.m中要用到引入的类的方法和属性时,不还是要#import头文件一次,是的这个是对的,但编译器编译的时候只编译头文件的,所以你的.m中用#import与编译时间没太大关系

 

总结:

   1.一般如果有继承关系的用#import,如B是A的子类那么在B中声明A时用#import

   2. 另外就是如果有循环依赖关系,如:A->B,B->A这样相互依赖时,如果在两个文件的头文件中用#import分别声明对方,那么就会出现头文件循环利用的错误,这时在头文件中用@class声明就不会出错

   3.还有就是自定义代理的时候,如果在头文件中想声明代理的话如@interface SecondViewController:UIViewController时应用#import不然的话会出错误,注意XXXXDelegate是自定义的

  

 

 

 

    

 

 

 

 

© 著作权归作者所有

HelloSwift
粉丝 0
博文 56
码字总数 42710
作品 0
丰台
程序员
私信 提问
Struct与Class辨析

《2010 .NET面试题整理之基础篇》文中第十三题为: ========================================== 13、在dotnet中类(class)与结构(struct)的异同? Class可以被实例化,属于引用类型,是分配在内...

最美的回忆
2017/04/11
0
0
【C语言】取值符&和间接值*辨析

计算机程序在存储数据时必须跟踪三种基本属性: 数据是什么 信息在存储器中的 存储的是多少 众所周知,对于常规变量a,是存储地址,a是值。对于指针变量p,p是存储地址,则是值。下面通过一个...

realsa
2016/04/12
111
0
行为型模式:Visitor 访问者模式

行为型模式:Visitor 访问者模式 1、类层次结构的变化 类层次结构中可能经常由于引入新的操作,从而将类型变得脆弱... 2、动机(Motivation) 1)在软件构建过程中,由于需求的改变,某些...

flyhighly
2011/04/24
60
0
freemarker生成静态HTML页面,文件路径错误问题

package com.yangliu.test; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java......

liuyanghaa
2017/03/03
432
0
Spring的事务管理入门:编程式事务管理(TransactionTemplate)!!!

转载 自 http://blog.csdn.net/zq9017197/article/details/6321391 Spring可以支持编程式事务和声明式事务。 Spring使用事务管理器,每个不同平台的事务管理器都实现了接口:PlatformTransac...

garyxiong
2016/02/22
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

正则表达式匹配

请实现一个函数用来匹配包括 '.' 和 '*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '*' 表示它前面的字符可以出现任意次(包含 0 次)。 在本题中,匹配是指字符串的所有字符匹配...

Garphy
50分钟前
5
0
Laravel 5.1的多路由文件的配置

默认的路由配置文件只有一个, \app\Http\routes.php。 在同一个文件中写路由容易起冲突,文件会越来越大,就需要定义多个路由文件。 找到加载\app\Http\routes.php的文件, 打开\app\Provid...

mdoo
今天
5
0
Hibernate 5 开始使用指南前言

同时在面向对象软件和关系型数据库进行工作,可能会非常复杂和费时。数据在对象和数据库之间可能会不一致,然后导致开发成本会非常高。 Hibernate 是一个针对 Java 环境的对象关系映射(Obj...

honeymoose
今天
6
0
聊聊nacos ServiceManager的UpdatedServiceProcessor

序 本文主要研究一下nacos ServiceManager的UpdatedServiceProcessor ServiceManager.init nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/core/ServiceManager.java @Compone......

go4it
今天
7
0
正则表达式的使用(QQ格式的判断与空格的切割)

//正则表达式的使用 public static void main(String[] args) throws IOException, ClassNotFoundException { //test1("123456"); test2("-1 99 kk"); } /** * ......

zhengzhixiang
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部