内存管理(二)

//
//  main.m
//  8_11_pm_内存
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou3g. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {


        Person *p = [[Person alloc]init];      // retainCount  是 1
        p.name = @"曹操";

        [p release];       //retainCount 应该减为 0;

        //person对象已经被销毁,不能再通过指针操作。 只是标记删除,只有alloc时,才销毁。

//        for (int i = 0; i < 1000; i ++) {
//            NSLog(@"%@",p.name);
//        }

        /*

         1、创建自动释放池对象
         2、在自动释放池内,对 对象进行autorelease操作。
         3、自动释放池会记录对象(如果同一个对象,两次调用autorelease,该对象会被记录两次)
         4、当自动释放池销毁时,记录的所有对象,依次调用release方法

         */
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

        NSLog(@"----%lu",pool.retainCount);

        Person *p1 = [[Person alloc]init];

        p1.name = @"刘备";

        [p1 retain];    //  2
        [p1 retain];

        [p1 autorelease];  //  2
        [p1 autorelease];

        NSLog(@"%lu",p1.retainCount);

        //销毁自动释放池

        [pool release];

        //release 与drain的区别在于,release把垃圾和垃圾桶都销毁了,drain只是把垃圾清除。
//        [pool drain];

        NSLog(@"%lu",p1.retainCount);
#pragma mark ----------自动释放池的第二种写法

        //mrc两种都支持,arc只支持第二种


        Person *p2 = [[Person alloc]init];
        [p2 retain];

        NSLog(@"%lu",p2.retainCount);

        @autoreleasepool {

            [p2 autorelease];
            NSLog(@"-------%lu",p2.retainCount);
        }

        NSLog(@"-------%lu",p2.retainCount);


        //pe指向的对象的引用计数为1

        //如果只写一句[p2 release];对象正常销毁,不存在内存问题,

        //如果不写[p2 release]; main函数运行结束后,局部变量pe被销毁,没有指针指向对象,造成内存泄露
        //如果写了不止一次,那叫过度释放,本质是野指针异常。

        [p2 release];


#pragma mark  --------------内存之copy






        Person *p3 = [[Person alloc]init];
        p3.name = @"三弟";
        p3.age = 18;


        //p4指向拷贝后的新对象。
        Person *p4 = [p3 copy];


        NSLog(@"%@",p4.name);
        NSLog(@"%lu",p4.age);







        //深拷贝,浅拷贝

        //深拷贝,拷贝的是对象,即创建了新的对象。
        //person类实现的是深拷贝,Student实现的是浅拷贝
        NSLog(@"%@",p4);
        NSLog(@"%@",p3);

        p3.release;

        p4.release;

        //浅拷贝,拷贝的是指针,拷贝的是原来的对象,没有创建新的对象。

        Student *s = [[Student alloc]init];
        Student *s1 =[s copy];

        NSLog(@"%@",s);
        NSLog(@"%@",s1);

        //字符串的retainCount
        //常量字符串的retainCount是最大值
#pragma mark ------------NSString的内存管理
        //字符串是一个很特殊的类,有时在常量区,有时在堆区。
        //内存管理只参考内存管理原则,即影响引用计数的5个方法。

        //因为存储在常量区
        NSString * str = @"张飞";
        NSLog(@"%lu",str.retainCount);
        NSString *str3 = [str copy];

        NSLog(@"%lu",str3.retainCount);

        NSString *str2 = [[NSString alloc]initWithFormat:@"德邦"];

        NSLog(@"%lu",str2.retainCount);

        //对常量区的进行release相当于没有进行操作

        NSString *str4 = [[NSString alloc]initWithFormat:@"1"];

        NSLog(@"%lu",str4.retainCount);

        //NSString类型的对象,调用copy得到的结果

        NSString *str5 = [[NSString alloc]initWithFormat:@"武松打虎"];

        NSString *str6 = [str5 copy];

        NSLog(@"%p",str5);
        NSLog(@"%p",str6);
        NSLog(@"%lu",str5.retainCount);


        //copy与mutablecopy

        //对象调用copy方法得到的是不可变的对象
        //对象调用mutablecopy,得到的是可变的对象

        NSArray *arr = @[@"1",@"2",@"3"];

        NSMutableArray *muarr = [arr mutableCopy];

        [muarr addObject:@"4"];
        NSLog(@"%@",muarr);

    }
    return 0;
}

如果要想实现copy,必须遵守NSCopying 协议,还要改写copyWithZone方法。

//
//  Person.h
//  8_11_oc内存管理
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou3g. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject<NSCopying>
{
    NSString *_name;
    NSInteger _age;
}

@property(nonatomic,copy) NSString *name;
@property(nonatomic,assign)NSInteger age;

@end
//
//  Person.m
//  8_11_oc内存管理
//
//  Created by lanou3g on 15/8/11.
//  Copyright (c) 2015年 lanou3g. All rights reserved.
//

#import "Person.h"

@implementation Person


- (void)dealloc
{

    NSLog(@"对象被销毁了,");


    [super dealloc];  //写在dealloc方法实现的最后一句,后面不能再有代码。
}


-(id)copyWithZone:(NSZone *)zone
{

      //以前的ios版本需要这样写,如果需要向下兼容(兼容低版本,可以这这句代码)
//    Person *temp = [Person allocWithZone:zone];


    Person *temp = [[Person alloc]init];

    temp.name = self.name;    //self表示调用copy方法的对象,即被拷贝的对象。
    temp.age = self.age;


    return temp;
}


@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值