本文共 2226 字,大约阅读时间需要 7 分钟。
1. 黄金法则 : 谁开发谁释放 , 谁污染谁治理 2. 引用计数 +1 的操作 : alloc, retain , copy 3. 引用计数 -1 的操作 : release, autorelease 4. 开辟空间 : alloc 销毁空间 : dealloc /** // 增加的次数 > 减少的次数 -- 内存泄露 ( 内存空间没有得到释放 ) // 增加的次数 < 减少的次数 -- 过度释放 // 增加的次数 = 减少的次数 如果还继续访问 , 就会有野指针问题出现 , 此时要把指针置为 nil; /* 1. 垃圾回收机制 gc(Garbage Collection), 由系统管理内存 , 开发人员不需要写任何代码管理内存 . 但是垃圾回收机制 在内存释放的时候不及时 (Java 开发中一直使用的就是垃圾回收技术 ) ; OC 2.0 之后支持垃圾回收 , 只用于 PC 端开发 ;java 也支持垃圾回收 . 2.MRC (Manual Reference Count) : 手动引用计数管理机制 , 需要手动的开辟内存 , 并且要手动的释放内存 , 都是通过代码形式来完成 . 3.ARC (Automatic Reference Count) : 自动引用计数管理机制 , 只需要开辟内存 , 而内存释放的代码由系统来写 , ARC 是基于 MRC 的 . 总结 : MRC 和 ARC 的内存管理方式都是和引用计数器相关 ; */ // 如何通过引用计数器管理内存 ? /* 图中的行为 OC 的操作 OC 中的方法 开灯 生成对象 alloc 需要照明 持有对象 retain / copy 不需要照明 释放对象 release / autorelease 关灯 销毁对象 dealloc ( 检测到引用计数器为 0 时 , 自动走这个方法 ) */
// alloc 的作用 : 在堆区开辟内存空间 , 并且让对象的引用计数由 0 到 1 // 引用计数 retainCount 是属于 NSObject 的 , 继承自它的类都拥有这个方法(可以使用点语法) - // 使用引用计数(retainCount) 要满足的条件: 1. 必须是OC对象 2. 必须在堆区,其他内存区域的引用计数都是无穷大的, %lu打印 18446744073709551615 ; %ld打印-1
- 已经释放掉空间的对象就叫做僵尸对象,操纵僵尸对象会引起Crash // 野指针 : 指向僵尸对象的指针就是野指针
// 内存管理的最终目的是想把开辟的空间给回收掉 , 所以无论通过哪一个指针变量进行 release 减 1 操作 , 都可以 // stringWithFormat: 创建字符串英文字符小于一个数的时候在常量区 , 大于某一个数的时候在堆区 // stringWithFormat : 创建的字符串是汉字时就存在堆区 // autorelease 和 release 的区别 // 不同点 : release 是立即让对象的引用计数器减 1, 而 autorelease 是在未来的某一时刻让对象的引用计数器减 1 //! autorelease 必须和自动释放池 (@autoreleasepool) 结合使用 , 如果没有自动释放池 , 就不会减 1 ; 它是在出 离它最近的自动释放池时 , 对对象的引用计数减 1 操作 // 使用遍历构造器创建的对象 , 我们不需要对他管理内存( 遍历构造器在创建的时候 , 在创建的时候 , 方法内部给这个对象添加了 autorelease 方法) - // 数组,字典,集合在添加元素的时候,内部会对这个对象的引用计数做一次+1
- // 数组在销毁的时候,会对数组中的每一个元素做一次引用计数-1的操作 [array release]
- /** 谁alloc谁release,只要我们没有看到引用计数加1的过程,那么就不要做减1的操作 便利构造器创建的对象都不需要release */
- // 优化的思想: 当一个对象不再使用的时候立即把他释放掉,达到优化内存的目的
---------------------------------------------------------- // 工程环境默认是ARC,需要手动改为MRC环境,才能使用内存管理的相关方法 打开僵尸对象调试:(不打开的话,操作僵尸对象不会报错): - UTF-8字符集,一个汉字占三个字节,gbk字符集,一个汉字占两个字节,比如varchar(10)类型的字段,UTF-8的汉字,只能存3个,gbk字符集的汉字却能存5个
copy:不是任何对象都可以接收copy消息,只有接受了NSCopying协议的对象才能接收copy消息。 // 属性中对不可变对象的 copy 都是浅拷贝 , 对可变字符串的拷贝就是深拷贝 ; - 浅拷贝: 拷贝的是指针(地址),并且让指针指向的对象引用计数+1
- 深拷贝: 新开辟一块内存,空间大小和原来对象大小相同,而且里面存储的数据也相同,此时没有影响到原来对象的引用计数
转载地址:http://vcuii.baihongyu.com/