1. 内存管理
1.1 进程空间
代码区:只读
全局区:进程启动时分配,进程结束时释放
栈区:局部变量,自动分配和释放内存
堆区:所有的对象,是自由区,分配和释放都要程序主动进行
内存管理主要是对堆区进行管理。所谓的管理,其实就是分配和释放空间。
1.2 iOS的内存管理方式
Reference Counting(引用计数器)
1) MRC Manual Reference Counting(手动的引用计数器)
2) ARC Automatic Reference Counting(自动的引用计数器)
垃圾回收机制
只有Mac OS X 10.5开始支持 最新的系统可能又不支持了
2. MRC
2.1 当创建一个对象时(alloc, new, copy),此对象的引用计数为1.
2.2 当你需要使用一个别人创建好多对象时,为了防止在我使用此对象期间别人释放这个对象,我要将此对象的引用计数器加1. 只要给对象发消息"retain",对象的引用计数器就会加1.
2.3 当你指向的对象不再需要时,你有责任将对象的引用计数器减1,给对象发"release"消息就可以让对象的引用计数器减1.
如果忘了向对象发"release"消息,对象有可能永远不会被释放,造成内存泄露。
2.4 当对象的引用计数器减到0,说明已经没有任何引用在使用对象了。对象就会被系统销毁掉,销毁之前,对象的一个方法会被自动调用,以通知对象:“你马上就要死啦”,这个方法叫:"dealloc",对象占用的内存空间就会被释放。
注意,dealloc方法是自动调用的,永远不要主动调用dealloc方法。在dealloc方法中调用父类的dealloc方法除外。
3. MRC内存管理原则
5.1 谁创建的对象,谁就有责任release这个对象;
5.2 谁retain了这个对象,谁就有责任release这个对象;
5.3 当我们使用一个已经创建好的对象时,为了防止对象在使用期间被释放,应该给对象发送"retain"消息。
最终要打到的目的是有几个引用指向(使用)了对象,对象的引用计数就应该是几,如果没有引用指向对象,对象的引用计数就应该为0.
//
// main.m
// day03-3
//
// Created by tarena on 14-3-19.
// Copyright (c) 2014年 tarena. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "TRStudent.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
TRStudent* stu1 = [[TRStudent alloc]init]; //RC=1
NSLog(@"stu1 addr:%p", stu1);
[stu1 method];
NSLog(@"stu1 RC:%ld", [stu1 retainCount]);
TRStudent* stu2 = stu1;
[stu2 retain]; //通知引用计数器加1 RC=2
NSLog(@"stu2 RC:%ld", [stu2 retainCount]);
[stu1 release];//通知引用计数器减1 RC=1
NSLog(@"stu1 RC:%ld", [stu1 retainCount]);
NSLog(@"stu2 addr:%p", stu2);
[stu2 method];
[stu2 release]; //RC=0,此时会调用dealloc方法
NSLog(@"stu2 RC:%ld", [stu2 retainCount]); //此时RC=0,对象已经销毁,不能发送消息,此时会报错。但如果在上面使用了stu2=nil就不会报错
}
return 0;
}