iOS - 内存管理机制

学习要点:

1.  Reference Counting引用计数机制

2. 了解MRCAPCGC

3.  AutoreleasePool运行机制

4. 如何避免Retain cycle

 

Reference counting引用计数机制

 

Cocoa上基本的内存管理机制就是引用计数,通过一个reference countretainCount来计数,有一个引用就加1,释放就减1reference count0,就释放对象。

 

如果需要持有一个对象,那么对其发送retain,如果之后不再使用该对象,那么需要对其发送release(或者autorealse),每一次对copy,retain,alloc或者new的调用,需要对应一次releaseautorealse调用。

 

常用关键词

alloc就是开辟一块内存,引用计数为1

new是较为老式的写法后来引入了alloc +init这种写法,可以把分配内存和初始化操作分开。

assign就是直接赋值,引用计数不变,当数据为int, float等原生类型时,可以使用assign

retain引用计数加1,返回一个引用。

release引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。

copy复制内容,在你不希望ab共享一块内存时会使用到。ab各自有自己的内存。

nonatomic/atomic表示该属性是否是对多线程安全的,atomic会自动加线程锁,但效率较差,默认为atomic

 

什么是MRCAPCGC

Cocoa上有三种内存管理机制,MRCAPCGCGC由于效率问题从未在IOS是支持,目前基本已经不再使用,现在使用的主要是MRCAPC

 

Manual Referecen Counting(MRC)即手动引用计数,你需要手工维护所有的retainrelease计数,你必须确保他们一一对应。

 

Automatic Reference Counting,自动引用计数,ARC开启时,编译器将自动在代码合适的地方插入retain, releaseautorelease只需要像往常那样编写代码,只不过不写retain,releaseautorelease三个关键字就

 

strongweak的区别

strongweakAPC中新加入的两个属性,

 

strong你可以简单理解为拥有对象的所有权。只要该指针指向某个对象,那么这个对象就不会被销毁。反过来说,ARC的一个基本规则即是,只要某个对象被任一strong指针指向,那么它将不会被销毁。如果对象没有被任何strong指针指向,那么就将被销毁。

 

在默认情况下,所有的实例变量和局部变量都是strong类型的。可以说strong类型的指针在行为上和MRC时代retainproperty是比较相似的。

 

weak使用权指针。weak类型的指针指向对象,但是并不会持有该对象。

 

weak另一特点是归零,在一个对象销毁时在ARC机制作用下,所有指向这个对象的weak指针将被置为nil。释放不当造成的空指针是经常会碰到的问题,c/c++使用多重指针的一种重要原因。使用ARC以后,不论是strong还是weak类型的指针,都不再会指向一个dealloced的对象,从根源上解决了意外释放导致的crash

 

https://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

 

AutoreleasePool要点

1.  AutoreleasePool核心是一个队列,每当你调用[blah autorelease]是时候,系统会在AutoreleasePool中注册一下,当你调用[poolrelease]的时候,系统会负责给队列中的每一项派发一个release

 

2.  [autorelease]是可以重复调用的,但你需要添加相应的retain来平衡。

 

3.还有一个新加入的方法[pool drain]APC下与release相同,GC下这个方法触发强制回收,而[pool release]no-op

 

4.老式的autoreleasepool看起来像这样子,

 

NSAutoreleasePool*pool = [[NSAutoreleasePool alloc] init;

 

// Codebenefitting from a local autorelease pool.

 

[poolrelease];

 

新式的写法如下,这种方式更快,根据苹果官方的说法autoreleasepoolNSAutoreleasePool的一个实例,本质上应该没有什么变化,但更效率。

@autoreleasepool

 {

}


 

5. 一般来说main程序中有一个autoreleasepool,每个线程都需要有一个autoreleasepool。

同时,UI上每次事件处理时候开始的时候,ios会为我们自动生成一个autorelesepool,事件结束的时候释放掉。所以在事件处理中分配的对象在事件结束后就会释放掉,释放时间不确定。

6.在一些需要实时释放的地方可以加一个@autoreleasepool,当autoreleasepool中有大量的变量的时候是否回比较慢,最好拆分多个@autoreleasepool。

 

Retain Cycle

循环引用,典型的情况如下,

假设有三个对象,一个父类的父类,一个父类和一个子类。父类的父类持有父类的引用(retain),父类持有子类的引用(retain),子类持有父类的引用(retain)。父类的父类释放(release)父类,父类的父类被释放,而这时候父类和子类永远保持1的引用,游离在外。


解决Retain Cycle的办法就是ARC中使用__weak__unsafe_unretained弱引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值