MRC内存管理:Manual Reference Counting
一、人工引用计数:
内存的开辟和释放都由程序代码进⾏行控制。相对垃圾回收来说,对内存的控制更加灵活,可以在需要释放的时候及时释放,对程序员的要求较⾼高,程序员要熟悉内存管理的机制。
1、MRC的内存管理机制是:引用计数
2、让引用计数由0~1的方法:alloc、copy
3、让引用计数+1的方法是:retain
4、让引用计数-1的方法是:release、autorelease
5、让引用计数由1~0的方法:dealloc
6、得到内存的引用计数:object.retainCount
※注意:
①、引用计数是保存在内存中,不属于某个指针
②、每当你为一个对象开辟了空间(alloc,copy)或让引用计数+1(retain),使用完后,必须将引用计数-1(release),release必须与alloc、copy 一一对应!
③、当引用计数为1时,再使用release方法的时候,理论上是将引用计数由1~0的,但是实际上是不会的,因为xCode环境下会自动调用dealloc方法将内存释放。
④、若你多次访问已经释放的空间会出现两种情况:能够正常访问或者程序崩溃
⑤、若过度释放,程序一定会崩溃
⑥、当对象释放后,为防止过度释放和访问不存在的空间,可以将对象设置为nli,因为给空对象发送消息,不会引起程序崩溃
⑦、谁使用了alloc、retain、copy就由谁释放
特例:NSString和NSNumber创建出来的引用计数都是”-1”,凡是字面量创建出来的对象都会去到常量区里
7、自动释放池
@autoreleasepool {}
①、autorelease方法的使用必须要在自动释放池里使用,在自动释放池外使用,不见效
②、在自动释放池内部调用的autorelease,会在自动释放池释放时,释放对应对象
③、自动释放池,在右大括号处释放 自己
⑤、利用autorelease释放时,过度释放,会崩溃在自动释放池的右大括号处
二、协议
1、协议是一系列方法的集合,对于协议本身是不需要方法的实现
2、创建协议:OS X选项中的Objective - C File
3、协议只有声明,没有实现,所以也没有.m文件
4、它以@protocol开头,以@end结束
5、不可以在协议内写实例变量,只能写方法
6、协议中的方法分别为两类:
①、必须实现的方法:@required
②、可选实现的方法:@optional
7、若让类遵守协议,必须先应用相对应的协议文件#import
8、协议在父类名称后面用<>写起来,一个类可以遵守多个协议,多个协议之间用逗号隔开
9、协议方法实现写在类的.m文件中,无需在.h中声明
三、有关copy的伪拷贝、浅拷贝、深拷贝
1、伪拷贝:只拷贝对象的地址,源对象和新对象指的是同一个对象
![](https://img-blog.csdn.net/20160326142847198?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
2、浅拷贝:创建新的对象空间,拷贝属性空间地址,拷贝属性地址,对象不同,但两者属性空间公用一块内存空间
![](https://img-blog.csdn.net/20160326143601344?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
3、深拷贝:创建新的对象空间,创建新的属性空间,拷贝属性内容;对象不同,属性不同空间不同,两者之间毫无任何关系。
![](https://img-blog.csdn.net/20160326144142102?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
4、想要定义类具有copy功能,就必须遵守NSCopying协议
5、copy方法:会调用对象的协议方法 -(id)copyWithZone:(NSZone *)zone;
①、伪拷贝
-(id)copyWithZone:(NSZone *)zone
{
return [selfretain];
}
②、浅拷贝
-(id)copyWithZone:(NSZone *)zone
{
//产生一样的对象空间
Student *stu = [StudentallocWithZone:zone];
//拷贝属性
stu.name = [self.nameretain];
stu.sex = [self.sexretain];
return stu;
}
※注意:其中伪拷贝和浅拷贝中的retain只是将引用计数+1;
③、深拷贝
-(id)copyWithZone:(NSZone *)zone
{
//拷贝对象空间
Student *stu = [StudentallocWithZone:zone];
//创建的属性内容空间
stu.name = [[NSStringalloc]initWithString:self.name];
stu.sex = [[NSStringalloc]initWithString:self.sex];
return stu;
}
※:普通变量直接赋值即可,即NSInteger、CGFloat、char,例如,stu.age = self.age;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)