内存管理

来源:互联网 发布:豫广网络机顶盒wifi 编辑:程序博客网 时间:2024/05/22 00:23

计数器原理

retain

计数器在对象里面retainCount【保留计数】
get方法可以用点语法
retainCount保留计数或者引用计数
[xiaohong retain];
1.首先,使指针指向的对象计数器➕1
2.然后返回当前xiaohong指向的对象的地址
计数器➕1之后,就会拥有对象空间绝对的使用权

release

只会使计数器➖1
只释放,不会改变指针的值
当计数器理论上理论为0,调用真正的对象销毁函数—dealloc【可重写此方法】【自动调用】

C++是构造函数:创建对象时自动调用的函数
C++的构造函数:与类名一样,没有返回值【无参(没有返回值类型)、有参】

OC 初始化init方法和C++的构造函数类似 手动调用
功能:初始化对象的成员变量

C++:析构函数【对象销毁时自动调用的函数】
在构造函数前加上~ ~类名(){}

OC:销毁函数 -dealloc【计数器为0时自动调用】

如果使用已经释放的对象,那么后果是不可预测的,非常严重的

当多一个指针指向对象的时候,这个对象计数器+1 retain
指针用完,不再指向对象,对象计数器-1 release

黄金法则

内存管理比较混乱,有些对象创建之后,用完了可以release释放,有些创建对象之后,就不能再次release
如何解决上面的混乱??
要遵守OC内存管理原则/法则:黄金法则
alloc/new/copy/mutableCopy会使对象计数器置为1【不是➕1】
retain使对象的计数器➕1
/因为OC字符串是在内存的数据区,虽然继承NSObject,拥有引用计数成员变量,但是很遗憾,不能修改
【黄金法则】
当我们程序员自己用alloc /new/copy/mutableCopy/retain开头的函数,把对象地址赋给一个新的指针变量(拥有了对象的绝对使用权),指针用完对象用完之后,不再使用对象的时候,那么指针应该立即release/autorelease(放弃绝对使用权)。每个指针只需要管理好自己就可以了,不需要管理其他的指针(个人顾个人原则),释放之后的指针就不要操作原来的对象了。
【结论】
1.只有程序员自己写出来alloc /new/copy/mutableCopy/retain这些函数,用完指针之后,要对应出现一个release/autorelease,如果没有上面的函数,就不要管。
只有出现了alloc /new/copy/mutableCopy/retain这些函数➕1了,才需要release/autorelease➖1
2.什么时候retain?
当一个对象多出一个指针指向的时候
以后我们在写代码的时候,都要遵守黄金法则(很灵活)

堆空间

1.忘记释放—>内存泄露
2.过早/过早释放—>内存崩溃
3.多释放—>崩溃

内存管理:管理的是堆空间

OC的对象绝大部分都在堆空间里,所以我们必须要进行内存管理,解决1.内存泄露;2.内存崩溃

一个指针指向堆空间 ➕1 retain
用完一个指针➖1 release

NSString * str = [str1 copy];

深浅拷贝

mutableCopy 把一个对象拷贝成一个可变对象【不管原来对象是否可变】

自定义的普通类没有可变不可变之说【官方的才有】
copy : copyWithZone
在使用copy或者mutableCopy的时候,使用的对象所述的类必须要遵守协议NSCopying协议或者NSMutableCopying的协议,实现里面的方法
因为在执行copy函数的时候,内部会调用当前对象的copyWithZone方法,所以使用copy之前,必须要遵守协议,实现copyWithZone方法

NSString NSArray NSDictionary 这些类遵守了拷贝协议,实现了里面的方法,可以直接拷贝
而且字符串对象常常用拷贝函数
其他类:应遵守协议,实现函数

【深拷贝】拷贝的是对象空间
【浅拷贝】引用(只会让对象计数器加1)