概述
C和OC(或者以后可能会学到的其他语言,如swift、c++、Python),有很多功能或定义相近的概念,这些概念往往容易令人混淆。本篇文章会不断更新,我们一起对这些概念做一个横向类比,以更好地理解概念之间的异同。
概念比较方法
比较系统给出的概念时,适用场合、使用方法、使用效果三方面谈
比较需要自定义的概念时,除上述三个方面外,还应注意定义方法
目录
概念比较
继承、组合、分类
定义方法不同
- 继承的文件命名为新类名,在声明类的时候,用“: 被继承者”表示
- 组合的文件命名为新类名,在定义成员变量的时候,实际上是定义了一个指向被组合对象的指针
- 分类的文件命名为“原类+分类功能”
使用场合不同
- 当一个类和另一个类有共同成员变量、方法,且两个类有明显的包含关系,用继承(如:Person类和Student类);若两个类有从属关系,用组合(如:Student类和Score类)
- 当不想新增类,仅希望扩充方法时,用分类
使用方法不同
- 继承重写方法后,原方法仍然可调用(super关键字)
- 分类重写方法后,原方法被覆盖不能调用
- 组合仅能调用被组合类的对象方法,无法调用类方法
retain和copy
使用场合不同
- retain为纯内存管理指令,主要目的是在内存管理时,使对象引用计数器+1
- copy的主要目的为复制指针或对象
使用效果不同
- retain一定会增加原对象引用计数器的计数值
- 浅复制会复制指针,同时增加原对象的引用计数器计数值;深复制会复制对象,且不会增加原对象的引用计数器计数值
autorelease和release
适用场合
两个概念均适用于内存管理场合
1. autorelease为半自动内存管理机制,在初始化对象时给对象发送一条autorelease指令,对象会被加入自动释放池。当自动释放池drain时,被加入该释放池的对象会自动执行一次release操作
2. release为纯手动内存管理指令,对象执行该指令后,引用计数器自动减一
@class、#import、#include
适用场合
- 希望声明一个类时,三种方法均可
- @class仅能声明该类,编译时并不会执行拷贝操作,编译器无法识别该类的方法,常用在交叉引用场合(如Person类的Pet属性为Dog指针,Dog类的Master属性为Person指针)
- #import和#include均用在希望声明类,同时希望使用相关方法的场合
使用方法
均在.h文件头部使用
使用效果
- @class仅能声明一个类
- #include可以复制一个类的.h头文件
- #import在复制头文件的同时,可以防止头文件被重复复制(条件编译原理)
@property、@synthesize
适用场合
- @property使用在interface中
- @synthesize使用在implementation中
使用效果
- @property用于定义一个实例变量的同时,自动声明这个实例变量的setter和getter
- @synthesize用于自动生成该变量的setter和getter方法的实现
- 当没有@synthesize的时候,@property可以会同时完成声明及实现
其他
注意下@property的几种参数(readonly、nonatomic、retain、strong、getter=isBOOL)
方法和函数
定义方法
- 方法分为类方法和对象方法,分别以-和+开头,以(返回值)+方法名+:(传入参数类型)形参名 声明
- 函数 返回值类型 函数名 + (形参列表)
使用方法
- 方法需要类或对象通过发送消息调用
- 函数可单独调用
NSLog和printf
使用场景
- NSLog用于打印OC对象
- printf用于打印字符串
使用方法
- NSLog(@”“,变量名)
- printf(“”,变量名)
使用效果
- NSLog会在打印字符串后自动添加\n
- printf需要手动添加\n
数组名和指针
本质区别
- 数组名不占内存
- 指向数组的指针有自己的内存,内存中存了被指数组第一个元素的内存地址
使用方式
- 数组名[索引号]用来访问指定成员变量
- 指针名+n用来访问指定成员变量
static和extern
使用场景
均可用于修饰变量、函数
深拷贝和浅拷贝
数组、枚举、结构体
使用场景
- 数组用于存放相同数据类型的多个数据
- 枚举用于存放一些选项(本质是被宏定义以后的整型数组)
- 结构体可用于存放不同数据类型的多个数据
使用方法
定义
- 数据类型 数组名[数组长度] = {初始化值}
- enum 枚举名{选项一,选项二,选项三…};
- struct 结构体名{数据类型 变量名;数据类型 变量名;…;}结构体变量名;
访问
- 数组名[索引号];
- 这个。。有访问吗?
- 结构体名.变量名;结构体名->变量名
C数组和OC数组
本质区别
C数组是基本数据类型,OC数组是对象。所以OC数组有方法、有成员变量、需要定义、需要进行内存管理