OC中的内存管理以及协议的详解

OC中内存管理,引用计数的变化

        从0~1alloc copy

   +1 retain

   -1 release autorelease

       从1~0dealloc


#+1/-1的内存管理

    //引用计数:0 ——1

    Student *stu =[[Student  alloc]init];


    //retainCount属性,就是内存的引用计数

    NSLog(@"stu.retainCount = %ld",stu.retainCount);

    

    //retain 让引用计数+1

    Student *stu1 = [stu retain];   //1 -> 2

    NSLog(@"stu = %ld",stu.retainCount);

    NSLog(@"stu1 = %ld",stu1.retainCount);

 

    Student *stu2 =stu1;  //2 -> 2

    NSLog(@"stu1 = %ld",stu1.retainCount);

    NSLog(@"stu2 = %ld",stu2.retainCount);

    

    //引用计数是保存在内存中,不属于某个指针

    

    [stu2 retain];  // 2 -> 3

    NSLog(@"stu = %ld",stu2.retainCount);

    

    //release  让引用计数-1

    [stu2 release];  //3 ->1

    stu2 =nil;

    NSLog(@"stu = %ld",stu.retainCount);

    

    [stu1 release];  //2 ->1

    stu1 =nil;

    NSLog(@"stu = %ld",stu.retainCount);

    

    [stu release]; //1 ->1

    stu = nil;

    //内存实质上不会将引用计数从1-0

    //而是直接将内存释放

    

    //再次访问空间会出现两种情况

    //1.正常访问

    //2.程序崩溃

    NSLog(@"stu = %ld",stu.retainCount);

    

    //过度释放

    //程序一定会崩溃

    [stu release];

    //当将对象释放后,为防止过度释放和访问不存在的空间

    //可以将对象设置成nil

    stu = nil;

    

    //给空对象发消息,不会引起程序奔溃

    [stu release];

    [stu release];

    [stu name];

   

    Student *student =[[Student alloc]init];

    [student retain];   //1 -> 2

    [student retain];  //2 -> 3


#autorelease


//autorelease 在自动释放池释放时释放

    //自动释放池

    @autoreleasepool {

        //在自动释放池内部调用的autorelease

        //会在自动释放池释放时,释放对应的对象

        //自动释放池,在右大括号处释放自己

        //在以后的某个时间,自动释放

        [student autorelease];

        student.name =@"liuxing";

        NSLog(@"student = %ld",student.retainCount);

//        [student autorelease];

//        [student autorelease];

//        [student autorelease];

//        [student autorelease];

    }  //利用autorelease 释放时,过度释放,会崩溃在括号处

    NSLog(@"student = %ld",student.retainCount);

    

    

    //st 原本的空间产生泄漏

    //st1 所指向空间,产生过度释放

    Student *st = [[Student alloc]init];

    Student *st1 = [[Student alloc]init];

    st = st1;

    

//    [st  release];

//    [st1 release];

//    st = nil;

//    st1 = nil;

    

    NSString *str = [NSString stringWithFormat:@"lanou"];

    [str retain];

    [str retain];

    NSLog(@"str = %ld",str.retainCount);

    

    [str release];

    [str release];

    [str release];

    

    //常量区

    str = @"lanou";

    [str release];

    

    //当用无符号输出时,-1对应最大值

    NSLog(@"str = %lu",str.retainCount);

    [str release];

    

#内存管理法则:

    //1.看到有allocretaincopy、就必须由release/autorelease

    //2.谁使用allocretaincopy就由谁释放


    //真正释放对象空间时,被系统自动调用

    //释放本对象的所有空间

    -(void)dealloc

    {

    NSLog(@"Student 对象被释放了!!!!");

    [super dealloc];

    }


#copy三种拷贝方式及用法详解


 三种拷贝方式:

 1.伪拷贝:只拷贝对象的地址

 2.浅拷贝:创建新的对象空间,拷贝属性地址

 3.深拷贝:创建新的对象空间,创建新的属性空间,拷贝属性内容

       伪拷贝:原对象和新对象指的是同一个对象

       浅拷贝:对象不同,但两者属性共用一块内存空间

       深拷贝:对象不同,属性空间不同,两者之间无任何关系


以下的三种拷贝在.m文件中实现

伪拷贝

-(id)copyWithZone:(NSZone *)zone

{

   return [self retain];


}


深拷贝

-(id)copyWithZone:(NSZone *)zone

{

    //拷贝对象空间

    Student *stu = [Student allocWithZone:zone];

    //创建新的属性空间    属性重新指向

    stu.name = [[NSString alloc]initWithString:self.name];

    stu.sex =[[NSString alloc]initWithString:self.sex];

    stu.hobby = [[NSMutableString alloc]initWithString:self.hobby];

    stu.score = self.score;

    stu.age = self.age;

   

   return stu;

}


浅拷贝

-(id)copyWithZone:(NSZone *)zone

{

    //产生一样的对象空间

    Student *stu =[Student allocWithZone:zone];

    //拷贝属性

    stu.name = [self.name retain];

    stu.sex =[self.sex retain];

    stu.hobby =[self.hobby retain];

    stu.score =self.score;

    stu.age =self.age;

    return stu;

}





#协议
(协议是一系列方法的集合,对于协议本身是不需要方法的实现; 
一个类可以遵守多个协议,多个协议之间用逗号隔开;
 协议只有声明没有实现,所以也没有.m文件;
协议可以被多个类去遵守)

如果要让一个类去遵守这个协议,那么就在这个类的.h文件中父类方法旁以< >尖括号的形式导入协议,并且要import导入协议文件

协议以@protocol开头,@end结束

协议中方法分为两类:

一、必须实现的方法,二、可选实现的方法

必须的

@required    //默认

-(void)makemoney;

-(void)cooking;

可选的

@optional

-(void)handsome;


要想自定义类具有copy功能

就必须遵守NSCopying协议

copy方法,会调用对象的协议方法

-idcopyWithZone:(NSZone *)zone


//student1 =[student2 copy];

//NSLog(@"hello world");

































  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值