【iOS-#import <> ““, @class和C- #include<> ““, 】

前言

寒假分享会的遗漏问题总结
请添加图片描述

引入

在C/CPP语言里,引入某个头文件的操作

#include<iostream>
#include<string>

也有

#include "string"

同样在OC里面 引入某个类会用到 #import关键字

#import "LoginViewController.h"
#import "LoginView.h"
#import "RegisterViewController.h"

或者

#import <AFNetworking.h>

在寒假学习优化代码的时候知道了向前声明@Class操作,区分和学习一下它们三个。

import 和 @class区别

在iOS中我们经常会在.h和.m中引入一些类啊等等一般用的是#import来进行声明,可能也见到在.h文件进用@class来声明的,那么#import和@class进行声明 到底有什么的区别呢?

import

import会包含这个类的所有信息,包括实体变量和方法(.h文件中),而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,后面会再告诉你。(在头文件中, 一般只需要知道被引用的类的名称就可以了。 不需要知道其内部的实体变量和方法,所以在头文件中一般使用@class来声明这个名称是类的名称。 而在实现类里面,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。)

#import 就是把被引用类的头文件走一遍,即把.h文件里的变量和方法包含进来一次,且仅一次,而@class不用,所以后者编译效率更高。

在编译效率方面考虑,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。

@class则不会。

@class只是简单的一个声明告编译器有这个类不让其报错,那么.m中要用到引入的类的方法和属性时,不还是要#import头文件一次,是的这个是对的,但编译器编译的时候只编译头文件的,所以你的.m中用#import与编译时间没太大关系

请添加图片描述

有ClassA ClassB,在B里面想初始化A,必须使用import.

当你只需要声明某个类在h文件的时候@Class一般更加高效。当然,在m文件里面使用它的时候需要import它的h文件

使用场景

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

// ClassA.h
#import "ClassB.h"

@interface ClassA : NSObject
@property (nonatomic, strong) ClassB *b;
@end

// ClassB.h
#import "ClassA.h"

@interface ClassB : NSObject
@property (nonatomic, strong) ClassA *a;
@end

在循环引用中,如果使用了#import导入头文件,会导致编译器无法正确处理类的依赖关系,从而出现“找不到类”的问题。这是因为#import是将整个头文件内容拷贝到导入文件的位置,而不是简单的引用头文件。当存在循环引用时,两个类的头文件都会相互导入,导致头文件中出现重复的类定义,进而导致编译错误。

请添加图片描述
使用@class ClassB即可

// ClassA.h
@class ClassB;

@interface ClassA : NSObject
@property (nonatomic, strong) ClassB *b;
@end

// ClassB.h
@class ClassA;

@interface ClassB : NSObject
@property (nonatomic, strong) ClassA *a;
@end

当编译器遇到@class ClassB时,会知道ClassB类的存在,而不会引起循环引用的问题。在实现文件中,通过#import导入ClassB类的头文件,即可使用ClassB类的定义。

总之,@class关键字可以在解决类的循环引用问题时起到重要的作用,它可以让编译器知道类的存在,而不会引起循环引用的问题。

继承使用import

当一个类需要继承另一个类时,可以使用#import来引入基类的头文件,并使得基类的定义在派生类中可见

// MyClass.h
#import "MyBaseClass.h"

@interface MyClass : MyBaseClass
// ...
@end

include<> 和 include""

#include是一个预处理指令,用于将一个文件的内容插入到当前文件中。

  • #include :用于包含标准库的头文件,这些头文件通常位于编译器的系统目录中。使用<>来包含头文件,编译器会从系统目录开始搜索头文件。
  • #include “filename”:用于包含用户自定义的头文件,这些头文件通常位于当前工程的源代码目录中。使用""来包含头文件,编译器会先从当前源文件所在目录开始搜索头文件,如果找不到,则继续在编译器的系统目录中搜索。
CPP的循环引用

使用#include时需要注意头文件的循环引用问题,如果存在循环引用,就需要使用前向声明(#pragma once或#ifndef等方式)或者重新设计头文件结构来避免循环引用。

import也是如此

总结

问题解决完成1

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值