标签:内存管理 retain release 对象之间的内存管理
内存管理:
1.作用范围:
任何继承了NSObject的对象,堆基本数据类型无效如:int a ,float price;;等
2.原理:
每个对象内部都保存了一个与之相关的整数,称为引用计数器,
当使用alloc new copy创建一个对象的时候,对象的引用计数器被设置为1
每给对象发送一次retain消息,可以使引用计数器+1;
给对象发送一条release消息,可以使引用计数器-1;
当一个对象的引用计数器为0时,那么它将被销毁,其占用的内存被系统回收,OC也会自动向对象发送一条dealloc消息,一般会重写dealloc方法,在这里,释放相关资源,一定不要直接调用dealloc方法:
可以给对象发送retaincount消息,获得当前的因数计数器数值。
3.retain 和release :
1,如果你想知道一个对象是不是被回收,方法:重写父类的dealloc方法:
注意:一定要调用super的dealloc方法,而且最后放在最后面调用。([super dealloc ])
2.如果一个对象调用了release 的操作,并且他的引用计数器已经为0,如果你再次调用他的release方法:这时候就会发生野指针错误:
野指针错误:你调用了本不属于你的内存空间,你既然已经释放了本来你的内存,那么现在那块内存已经不属于你了,你在调用release方法,说明你又声明那块内存是属于你的,这时候就会发生野指针 错误。
注意:当一个对象retain为0的时候,这时候你就不能再调用他的retainCound方法,因为一个被释放的对象,没有内存,不再去进行访问会发生野指针错误。
3.如果你在创建对象的时候,加上autorelease,那么编译器会在一个适当的时机释放对象,这 样就不需要你自己手动释放对象的内存了
4.内存管理法则:
1.谁创建,谁释放(“谁污染,谁治理”),如果你通过alloc ,new ,copy来创建一个对象,那么你必须调用release或autorelease ,如果不是你创建的,你就不用去释放。
2.一般除了alloc ,new copy之外的方法创建的对象都被声明了autorelease
3.谁retain ,谁release ,只要你调用了retain ,无论这个对象是如何产生的,你都要调用release;
5.对象之间的内存管理:
前提:如果一个类A作为另外一个类B的成员变量,并且访问A的数据成员的是否,如果在main函数中调用了类B的一个方法,这时候会调用A的对象进行初始化A的成员变量,当在该方法中销毁后,类B又访问了一个方法2,这时候仍然让类A的对象进行初始化操作,这时候会出现野指针错误,
原因:由于在方法1中已经释放了A对象,所以A对象所指向的成员变量的内存回收,如果你再进行调用,就会指向一个不属于自己的内存空间,这是很危险的。
解决办法,在set方法里里面设施对象的retain操作,并进行release,前提,是判断传进来的对象是不是本身。如果是本身那就释放掉原来对象的指向,如果是一个新的,那就没有必要进行release,因为,新对象本来计数器为0.你再release,就会错误;
代码如下:
类B 中的.M文件
- (id)initWithAge:(int)age{
if ( self= [super init]) {
_age = age;
}
return self;
}
#pragma mark 回收对象
- (void)dealloc {
// 释放Book对象
[_book release];
//[self.book release];
NSLog(@"student:%i被销毁了", _age);
[super dealloc];
}
#pragma mark - getter和setter
- (void)setBook:(Book*)book {
if (_book!= book) {
// 先释放旧的成员变量
[_book release];
// 再retain新传进来的对象
_book = [book retain];
}
}
- (Book *)book {
return _book;
}
#pragma mark - 公共方法
#pragma mark 读书
- (void)readBook {
NSLog(@"当前读的书是:%f", _book.price);
}
main函数:
void test(Student*stu) {
// book:1 引用计数器
Book *book = [[Book alloc] initWithPrice:3.5];
// book:2
stu.book = book;
// book:1
[book release];
//book2:1
Book *book2 = [[Book alloc] initWithPrice:4.5];
//book2:2
stu.book = book2;
// book2:2
stu.book = book2;
// book2:1
[book2 release];
// book2:1
stu.book = book2;//如果再次调用,book2的retaiin也不会变
}
void test1(Student*stu) {
[stu readBook];
}
int main(intargc, const char* argv[])
{
@autoreleasepool {
// stu:1
Student *stu = [[Student alloc] initWithAge:10];
// stu:1
//book:1
//book2:1
test(stu);
// stu:1
//book:1
//book2:1
test1(stu);
// stu:0
//book2:0
//book:1
[stu release];
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:内存管理 retain release 对象之间的内存管理
原文地址:http://blog.csdn.net/u012989536/article/details/47622391