标签:
无论编写任何程序, 都需要有效和高效地管理资源。内存资源则是重中之重, 都知道如果电脑内存如果不够用, 系统就能会卡, 反应尺寸, 那么手机也是一样的。在OC程序中对象一旦不需要了必须释放资源.
在一个复杂的系统中,可能很难精确地确定从何时起您不再需要某个对象。Cocoa定义了一些有助于使这一抉择变得更加容易的规则 和原则
如果使用alloc、new、copy、mutableCopy创建一个对象, 系统会给这个对象的内部引用计数器赋值1, 您也就拥有这个对象的所有权, 不是自己创建的也可以对对象进行retain操作也会拥有这个对象的所有权。注意如果您对对象retain操作, 其内部的引用计数器也会 +1操作
释放对象的所有权: 可以用release, 或者autorelease自动释放一个对象的所有权. 注意: 不一定release之后对象就一定被释放了, 他只是释放对象的所有权, 换句话来说只是将其内部的引用计数器 -1操作, 对象是否被释放要看内部的【引用计数器】为0
autorelease不是马上释放对象, 而是在一个运行循环(runloop)结束之后向所有等待释放的对象发送一条release操作, 详细介绍在后面
说简单点就是如果你引用给一个对象就拥有这个对象的所有权, 一个对象可以被N个所有者拥有, 如果有人拥有这个对象, 那么这个对象就一直存在, 如果没有人拥有就会在运行时被释放. Cocoa 制定了一个非常完美的策略来实现对象是否被释放
如果您在ARC项目中把一个class修改成非ARC状态之后在执行44行的时候会发现跑通了没报错, 而且他的retainCount值也是1, 首先解决这个现象需要在product-> scheme-> Edit scheme -> Diagnostics -> Enable Zombie Objects勾选上, 在运行就会出错了, 那么这里给你详细的解释是:
事实上obj的确已经被dealloc了,保留计数器的值也已经变成0了,其原来占用的内存也已经不可用了,但是原来这块内存中的内容还没有变(标记删除),将会在未来某个不确定的时间上被清理(就是runloop做的事),这就是为什么NSLog输出的obj保留计数器的值仍为1,而如果在此时再加上一个NSLog, 用1个僵尸对象调用一块被释放的坏内存, 于是程序crash
首先定义一个Student创建一个对象叫car
重写 car对象setter方法, 里面判断是否是同一个对象传进来, 如果不同对象需要对其旧对象释放, 新对象retain操作, 这样就拥有对象的所有权
下面是对象的retainCount值, 如果看不太明白自己动手操作一下就明白了.
每一个对象内部都有一个retainCount属性, 用来判断有多少个对象拥有它, 如果没有对象拥有它就被释放
如果向一个对象发送autoreleace消息之后, 不会立即被释放, 对象会被放入自动释放池中, 等待系统会在某一时间点, 对其释放池内部的所有对象进行一次releace操作,
项目中经常出现的就是2个对象互相引用, 你引用我, 我引用你, 这样他们内部的引用计数器始终不为0, 一直都被存在, 导致系统最后crash, 用一个图来说明
学生引用车, 车反过来引用学生, 导致2者都不能被释放, 互相咬着, 谁也不放谁
解决办法: 一端用assign, 一段用retain 即可
标签:
原文地址:http://www.cnblogs.com/MrTao/p/5854239.html