内存管理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存管理相关的知识,希望对你有一定的参考价值。
内存管理:
MRC:
因为iPhone内存有限, 所以要对内存及时管理, ios系统的内存管理不像C#, java等其他语言有回收机制, 所以他的内存就要程序员手动及时管理. 在开发当中1个对象被创建(alloc、new、copy)其内部会有一个引用计数器(retaincount, 默认是1), 如果你要是在某个地方引用这个对象需要对其retain(+1)操作, 如果不用他就需要及时release(-1), 这样系统就能知道有多少个对象在引用这个对象, 如果对象的引用计数器为0了那么系统就把这个对象释放了. 每一个对象被释放前都会调用dealloc方法.
僵尸对象: 引用计数器为0的对象就是僵尸对象, 换句话就是被释放的对象. 僵尸对象是不可复用的, 幻想一下人死了还能活过来吗.
野指针: 指向僵尸对象的指针就是野指针, 所以一般对象被释放之后会给值赋值nil, 这样就不会报错
野指针错误: 利用野指针去操作一块内存,EXC_BAD_ACCESS(code=1, address=0x20)
dealloc 方法一定要在最后调用 [super dealloc];
循环引用问题
@class 解决#import文件循环引用问题, 告诉编译器@class后面的就是一个类
对象循环引用
一端用assign, 一端用retain
autorelease
半自动释放 arc不允许你调用这个方法
会将对象放到自动释放池中, 当自动释放池被销毁, 会对池子中的所有对象进行一次release
5.0之前
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
对象销毁
[pool release]; / [pool drain];
5.0的写法
@autoreleasepool{创建自动释放池
不会改变对象计数器的值
}销毁自动释放池
延迟对象的释放操作, 不能精确的释放对象
内存占用较大的不建议使用, 长时间不释放对象非常耗内存
自动释放池都是以栈的形式存在
当一个对象调用autorelease方法时, 会将对象放到栈顶释放池中
注意:
如果系统中不包含new, alloc, copy, 那么这些方法都说已经autorelease了
ARC
iOS5出来一个非常好的就是ARC机制, 他不用程序员手动去管理内存, 完全由系统自动管理, 编译器在编译的时系统会自动加入release,retain, 不允许调用方法,
dealloc里 不能调用 [super dealloc], 不要直接调用, 系统自动调用
ARC原理, 此对象有没有强指针指向该对象
弱指针: __weak
强指针: __strong, 默认
MRC旧项目改 ARC新项目
edit —> refactor —> convert to ARC
证明是不是ARC项目
build settings 搜索auto —> objective - c ARC
ARC ,MRC共存
build phases 双击文件/回车 输入
-fno-objc-arc 非ARC
-f-objc-arc ARC
循环ratain
一端用strong 、一端用weak
ARC与MRC的性能对比:
ARC的性能是更好的,这主要得益于一些底层的优化以及autorelease pool的优化,这个从官方文档也能看到。但在一些情况下,ARC确实是更慢,ARC会发送一些额外的retain/release消息,如一些涉及到临时变量的地方,之所以添加这些额外的retain/release操作,是为了保证代码运行的正确性
property 里面参数都有什么,都是什么意思?
MRC
assign、retain、copy
ARC
assign、weak、strong、copy
公共
nonautomic、automic:原子性,nonautomic线程安全,automic线程安全,系统会给对象加一个线程锁。
getter:重命名方法名
readonly:只读
iOS9
nullable可以为null
nonnull不可以为null
说说assign与weak
什么时候用weak:一般在解决循环引用的时候用weak,比如delegate,或者该对象已经被强引用着就不需要在用strong 修饰,所以用weak
什么时候用assign:在MRC中解决循环引用的时候,修饰基本数据类型,ARC中不能修饰对象
有什么不同:weak修饰的对象如果对象没有强引用就会销毁,所以weak修饰的对象也会跟着销毁
assign修饰的只是简单的赋值
以上是关于内存管理的主要内容,如果未能解决你的问题,请参考以下文章