赞
踩
Manual reference Counting
与ARC是两种不同的内存管理机制。ARC是自动引用计数,有编译器在编译时自动插入内存管理代码。而MRC是手动引用计数,开发者需要手动管理对象的引用计数。//new方式和alloc init方式一样,只不过我们习惯了分两步走。
//MJPerson *person = [MJPerson new];
MJPerson *person = [[MJPerson alloc] init]; //1
//中间写我们想要的代码
[person release]; // 0
或者:
@autoreleasepool {
MJPerson *person = [[[MJPerson alloc] init] autorelease]; //1
//中间写我们想要的代码
}
MJPerson里面拥有MJDog,在MJPerson里面重写setDog方法。
- (void)setDog:(MJDog *)dog
{
if (_dog != dog) {
[_dog release];
_dog = [dog retain];
}
1,为什么要释放旧值?
如果将新值直接赋给实例变量,而没有堆旧值进行适当的释放操作,旧值的引用计数就从不会减少,对象的内存也不会释放,这就会导致内存泄漏。
2,为什么要retain新值?
当一个对象被复制给一个实例变量,为了确保对象在使用时保持有效,需要增加对象的引用计,这样可以保证在其他地方意外释放对象
3,为什么要检查对象是否相等?
如果_dog和传入的dog是同一个对象,旧值release后引用计数就为0,旧值就会被释放,这时再retain新值就报错。
如果时基本数据类型,就不用进行内存管理,如果是OC对象,setter方法就要这样写。
MRC下的@property只会生成setter和getter方法的声明,如果想生成_age成员变量和setter、getter方法的实现还要使用@synthesize关键字。
NSObject *a = [[NSObject alloc] init]; //执行完引用计数为1
[a release]; //执行完引用计数为 0,实例对象被释放。
a = nil; //此时,a变为了空指针。
[a release]; // 再给空指针a发送消息就不会报错了。
[a release];
NSObject *b = [[NSObject alloc] init]; //执行完引用计数为1
[b release]; //执行完引用计数为 0,实例对象被释放。
[b release]; // 此时,a 就变成了野指针,再给野指针 a 发送消息就会报错
下面话就看看使用不同的关键字修饰@property并且使用@synthesize
关键字,生成setter和getter方法实现有什么不同
使用assign生成的setter方法没有内存管理相关的东西,所以assign一般用来修饰基本数据类型,默认情况下就是assign
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
使用retain修饰,生成的setter方法有内存管理相关的东西,所以retain一般用来修饰对象类型。
- (void)setDog:(MJDog *)dog
{
if (_dog != dog) {
[_dog release];
_dog = [dog retain];
}
}
- (MJDog *)dog
{
return _dog;
}
五,自动生成释放池(AutoreleasePool
)
autorelease
是一种支持引用计数的内存管理方式,只要给对象发送autorelease消息,会将对象放在一个自动释放池(AutoreleasePool
)中,当自动释放池被销毁时,会对池子里的所有对象做一次release操作。其本质就是对对象的release的调用延迟,延长对象的生命周期。
这里只是发送release消息,如果当时的引用计数依旧不为0,则对象依然不会被释放,autorelease方法返回对象本身,且调用完autorelease方法后,对象的计数器不变。
autorelease的使用方法
NSAutoreleasePool* autoreleasePool = [[NSAutoreleasePool alloc] init];//创建自动释放池
Person* p = [[[Person alloc] init] autorelease];//方法释放池
[autoreleasePool drain];//销毁自动释放池
@autoreleasepool
{ // 创建一个自动释放池
Person *p = [[Person new] autorelease];
// 将代码写到这里就放入了自动释放池
} // 销毁自动释放池(会给池子中所有对象发送一条 release 消息)
六,MRC的优点
在使用ARC
时,开发者只需要关注对象的强引用和弱引用,无需关心对象的引用计数。而在使用MRC
时,开发者需要手动管理对象的引用计数,需要仔细地在合适的地方调用retain
、release
或autorelease
等方法,以避免内存泄漏和野指针问题。
总体而言,ARC是iOS开发中推荐使用的内存管理机制。它可以帮助开发者更专注于业务逻辑的实现,减少了大量的内存管理代码,提高了代码的可读性和可维护性。同时,ARC在性能上也不会比MRC有明显的劣势,因为编译器会在编译时进行优化,生成高效的内存管理代码。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。