OC语言 - 内存管理:alloc | retain | release

内存管理

1 - MRC(Manual Reference Count)人工引用计数:内存的开辟和释放由程序代码进行控制;ARC(Automatic Reference Count)自动引用计数。它不是自动管理内存,而是编译器帮助程序员默认加了释放代码

2 - 在 C 语言中使用 malloc 和 free 进行堆内存的创建和释放,堆内存只需要正在使用和销毁两个状态;两个以上的指针使用同一块内存,C 语言是无法记录内存使用者的个数的

引用计数

1 - alloc:  创建对象并获取对象所有权,引用计数从 0 变为 1

2 - retain:引用计数在原来的基础上 +1,并获得对象的所有权

3 - copy : 拷贝出一个新副本,将副本的引用计数置 1,并拥有副本的所有权

4 - release :      释放对象,引用计数立即 -1,并释放对象的所有权

5 - autorelease: 未来的某一时刻引用计数 -1,获取对象存在(不持有)并放弃对象所有权,可理解为 release 的自动延迟

注:避免频繁使用 autorelease

alloc | retain | release

1 - 代码示例:alloc、retain 和 release

// - Student.h

1 #import <Foundation/Foundation.h>
2 @interface Student : NSObject
3 
4 
5 @end

// - Student.m

 1 #import "Student.h"
 2 
 3 @implementation Student
 4 
 5 -(void)dealloc{
 6     NSLog(@"%@已经销毁",self);
 7     [super dealloc];
 8 }
 9 
10 @end

// - main

 1 #import <Foundation/Foundation.h>
 2 #import "Student.h"
 3 
 4 int main(int argc, const char * argv[]) {
 5     
 6     // alloc
 7     Student *student = [[Student alloc] init];// 1
 8    
 9     
10     // retain
11     [student retain];// 2
12     [student retain];// 3
13 
14     // release
15     [student release];// 2
16     [student release];// 1
17 
18     
19     [student release];// 1
20     // 此时 release 后则触发 dealloc,但是 retainCount 并不会马上回到 0,且指针变量本身也不会自动置 nil,依旧指向原来的地址,所谓的悬垂指针
21     NSLog(@"%p",student);// 验证:会打印出原地址
22     
23     student = nil;
24     [student release];// 空指针可无限制地 release,没有实际意义
25     NSLog(@"%lu",[student retainCount]);// 0  dealloc 被触发后必须手动置 nil,这样 retainCount 才会归 0
26     
27     // 如果对象被销毁后且没有手动置 nil,继续使用该对象则 crash
28     [student release];// crash
29     
30     return 0;
31 }

小结

1 - 当一个所有者(其可以是任何一个 Objective-C 对象)做了以下某个动作时,它就拥有了对一个对象的所有权

① 如果创建或者复制某个对象时,则拥有了该对象的所有权:alloc、allocWithZone:、copy、copyWithZone:、mutableCopy、mutableCopyWithZone:

② 如果没有创建对象,而是将对象保留使用,同样拥有该对象的所有权:retain

③ 如果你拥有了某个对象的所有权,在不需要某一个对象时,需要释放它们:release、autorelease

 

posted on 2018-09-11 09:26  低头捡石頭  阅读(81)  评论(0编辑  收藏  举报

导航