1.内存管理原则
如果对一个对象使用了alloc、[mutable]copy、retain,那么你必须使用相应的release或者autorelease。
2.管理范围
任何继承了NSObject的对象,对其他基本数据类型(int、char、float、double、struct、enum等)无效
3.内存管理对象
OC的对象:凡是继承于NSObject;
4.引用计数器
每个OC对象都有自己的引用计数器,是一个整数,表示“对象被引用的次数”,即有多少人正在使用这个OC对象
每个OC对象内部专门有4个字节的存储空间来存储引用计数器
5.引用计数器的作用
当使用alloc、new或者copy创建一个新对象时,新对象的引用计数器默认就是1
当一个对象的引用计数器值为0时,对象占用的内存就会被系统回收。换句话说,如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收,除非整个程序已经退出
6.alloc、retain、release函数
alloc 函数是创建对象使用,创建完成后计数器为1;只用1次。
retain是对一个对象的计数器+1;可以调用多次。
release是对一个对象计数器-1;减到0对象就会从内存中释放。
7.增加引用计数器
使用alloc方法来分配对象;
使用copy[WithZone:]或者mutableCopy[WithZone:]来copy对象的时;
使用retain消息。
8.减少引用计数器
使用[auto]release来递减计数器。
9.对象的销毁
当一个对象的引用计数器值为0时,那么它将被销毁,其占用的内存被系统回收
当一个对象被销毁时,系统会自动向对象发送一条dealloc消息
一般会重写dealloc方法,在这里释放相关资源,dealloc就像对象的遗言
一旦重写了dealloc方法,就必须调用[super dealloc],并且放在最后面调用
一旦对象被回收了,它占用的内存就不再可用,坚持使用会导致程序崩溃(野指针错误)
10.set方法的内存管理
如果你有个OC对象类型的成员变量,就必须管理这个成员变量的内存。
示例:
#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject
{
Car *_car;
}
- (void)setCar:(Car *)car;
- (Car *)car;
@end
@implementation Person
- (void)setCar:(Car *)car
{
if (car != _car)
{
[_car release];
_car = [car retain];
}
}
- (Car *)car
{
return _car;
}
- (void)dealloc
{
[_car release];
[super dealloc];
}
@end
11.@property参数
OC内存管理正常情况要使用大量的retain和release操作;
点语言可以减少使用retain和release的操作。
编译器对于retain展开形式
@property (retain)Dog*dog;
//展开为:
-(void) setDog:(Dog*)aDog;
-(Dog *)dog;
@synthesize dog = _dog;
//展开为:
-(void) setDog:(Dog*)aDog
{
if(_dog != aDog)
{
[_dog release];
_dog = [aDogretain];
}
};
-(Dog *)dog
{
return _dog;
};
copy属性
copy属性是完全把对象重新拷贝一份,计数器重新设置为1,和之前拷贝的数据完全脱离关系。
控制需不需生成set方法
设置@property的参数(二选一默认是readwrite)
readwrite :同时生成set方法和get方法(默认)
readonly :只会生成get方法
12.自动释放池与autorelease
autorelease给某个对象发送一条autorelease消息时,就会将这个对象加到一个自动释放池中
当自动释放池销毁时,会给池子里面的所有对象发送一条release消息
自动释放池的创建
// ios 5.0后(使用Xcode会自动创建)
@autoreleasepool
{
// ....
}
// ios 5.0前
NSAutoreleasePool *pool = [[NSAutoreleasePoolalloc] init];
// .....
[pool release]; // 或[pool drain];
13.规律
一般来说,除了alloc、new或copy之外的方法创建的对象都被声明了autorelease
比如下面的对象都已经是autorelease的,不需要再release
NSNumber *n = [NSNumbernumberWithInt:100];
NSString *s = [NSStringstringWithFormat:@"jack"];
NSString *s2 =@"rose";
14.个人小结
现在使用Xcode5.0及以上版本时,Xcode会自动进行内存管理,不需要人为编写代码来进行控制。苹果官方之所以优化内存管理机制,主要目的是在于将开发人员的注意力集中在程序功能研发和性能优化上,释放开发人员花费在内存管理上的大部分精力,而朝着开发创新的方向努力。
对于OC基础学习,只要了解其内存管理机制即可,为高级开发打下基础。