内存管理方式概述:
OC2.0提供两种内存管理方式:垃圾回收机制(gc)和引用计数;gc用于mac系统开发,iOS使用引用计数机制;
引用计数有两种形式:
MRC(人工引用计数Manual Reference Counting)需要程序员自己创建和释放对象;
ARC(自动引用计数Auto Reference Counting)是基于MRC,是iOS5.0提供的一种管理方式,对编译器进行优化,自动编译上内存释放代码;
Xcode默认是ARC模式,需要自己在工程文件里修改;
内存管理的方法
alloc:在堆区开辟内存,并且让堆区这块内存的引用计数由0变1;
retain:对原内存进行持有,将原内存的引用计数+1,并返回持有的内存的地址;
release:是将对象持有的堆区内存的引用计数立即 -1;
dealloc:继承自父类的方法,当对象的引用计数为0时,自动调用,销毁该对象的内存空间;
千万不要在main.m文件中自行调用dealloc方法;交由引用计数机制就好;
在自定义的类中,如果有自定义实例变量,需要重写dealloc方法;
-(void)dealloc{
[_name release];
[_sex release];
[super dealloc];
}//在重写的方法中,将所有对象类型的实例变量都释放掉;
//先释放实例变量再执行 [super dealloc];
以Person类为例
Person *per1 = [[Person alloc] init];
//开辟内存,引用计数由0变1;
Person *per2 = [per1 retain];
//per2 也能访问per1 开的内存,引用计数+1;
[per2 release];
//引用计数-1;
per2 = nil;
//释放后给对象赋空,安全释放;
Protocol协议
协议就是一套方法的声明,只有.h文件,没有实现文件;
遵守协议的类需要在实现文件中自行实现
建立协议文件
和建立类文件类似,选择Objective-C File
@protocol Working <NSObject>
@required // 加了required 标识的是必须实现的方法,默认是required
-(void)makeMoney;
@optional // 加了op�tional 标识的是可选实现的方法;
-(void)xiaBan;
@end
在类中遵守协议,需要先引入协议文件,然后在父类后面加<>;
#import "Working.h"
@interface Person : NSObject <Working>
copy
分为三类:伪拷贝,浅拷贝,深拷贝
自定义的类需要遵守NSCopying协议,实现协议中声明的方法;
实现NSCopying协议内容
-(id)copyWithZone:(nullable NSZone *)zone{
//伪拷贝,不开辟空间,实质上就是retain;
//return [self retain];
//浅拷贝,为对象开辟空间,但实例变量指向方法调用者的实例变量空间;
//Person *p = [[Person allocWithZone:zone] init];
//p.name = _name;
//p.sex = _sex;
//return p;
//深拷贝,真正的拷贝,开辟一个全新的空间,包括对象和实例变量都有了新的容身之处;
Person *p = [[Person allocWithZone:zone] init];
p.name = [_name mutableCopy];
p.sex = [_sex mutableCopy];
return p;
}
对可变对象进行拷贝,不管是用copy还是mutableCopy都是深拷贝;
对不可变对象进行拷贝,用copy是浅拷贝,用mutableCopy是深拷贝;
对于mutable的一点思考
mutable相对于可变这个意思来说,我觉得它更代表了一种对象指针和对象空间的一种分离特性;