zoukankan      html  css  js  c++  java
  • 内存管理高级(dealloc,alloc)

    内存管理高级

    内存管理高级:

    1.属性的内部实现原理

    2.dealloc内释放实例变量

    3.便利构造器方法的实现原理

    4.collection的内存管理

    name, age, gender

    自定义初始化方法

    便利构造器

    Student.h
    #import <Foundation/Foundation.h>
    @interface Student : NSObject <NSCopying>
    //重在对象, 使用retain; 重在内容, 使用copy
    @property (nonatomic, retain) NSString *name;
    @property (nonatomic) NSInteger age;
    @property (nonatomic, copy) NSString *gender;
    - (instancetype)initWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender;
    + (instancetype)studentWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender;
    @end
    Student.m
    #import "Student.h"
    @implementation Student
    @synthesize name = _name, age = _age, gender = _gender;
    #pragma mark - liftCycle
    - (instancetype)initWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender {
        if (self = [super init]) {
            //1
            _name = [name retain];
            _age = age;
            _gender = [gender copy];
            //2
            self.name = name;
            self.age = age;
            self.gender = gender;
        }
        return  self;
    }
    + (instancetype)studentWithName:(NSString *)name age:(NSInteger)age gender:(NSString *)gender {
        return [[[Student alloc] initWithName:name age:age gender:gender] autorelease];
    }
    
    - (void)dealloc {
        [_name release];
        [_gender release];
        [super dealloc];
    }
    #pragma mark - super
    - (NSString *)description
    {
        return [NSString stringWithFormat:@"name:%@ age:%ld gender:%@", _name, _age, _gender];
    }
    
    #pragma mark - accessor
    - (void)setName:(NSString *)name {
        if (_name != name) {
            [_name release];
            _name = [name retain];
        }
    }
    - (NSString *)name {
        return _name;
    }
    - (void)setAge:(NSInteger)age {
        _age = age;
    }
    
    - (NSInteger)age {
        return _age;
    }
    - (void)setGender:(NSString *)gender {
        if (_gender != gender) {
            [_gender release];
            _gender = [gender copy];
        }
    }
    - (NSString *)gender {
        return _gender;
    }
    #pragma mark - NSCopying
    -(id)copyWithZone:(NSZone *)zone {
        //浅拷贝
    //    return [self retain];
        
        //深拷贝
        //1.复制结构
        Student *student = [[Student allocWithZone:zone] init];
        //2.复制内容
        student.name = self.name;
        student.age = self.age;
        student.gender = self.gender;
        return student;
    }
    @end
    main.m
            Student *stu1 = [[Student alloc] initWithName:@"张三" age:18 gender:@""];
            NSLog(@"%@", stu1);        
            //想要对stu1对象做copy操作, Student类必须遵守<NSCoping>协议
            Student *stu2 = [stu1 copy];
            NSLog(@"%@", stu2);       
            [stu1 release];
            [stu2 release];     
            //属性的修饰词是copy
            NSMutableString *string = [[NSMutableString alloc] initWithFormat:@"zhangsan"];
            Student *student = [[Student alloc] init];
            student.gender = string;
            NSLog(@"%@", student.gender);        
            [string setString:@"zhangsanfeng"];
             NSLog(@"%@", student.gender);       
            [string release];
            [student release];

      针对系统的数据类型

            对不可变的数据类型, copy是浅拷贝

            NSString  *str1 = [[NSString alloc] initWithFormat:@"辉哥真帅哦哦!"];
            NSLog(@"%lu", str1.retainCount);//1
            NSString *str2  = [str1 copy];
            NSLog(@"%p", str1);
            NSLog(@"%p", str2);
            NSLog(@"%lu", str1.retainCount);//2

    对可变的数据类型, copy是深拷贝 

            NSMutableString *mStr1 = [[NSMutableString alloc] initWithFormat:@"小灰灰"];
            NSLog(@"mStr1:%p", mStr1);
            //copy: 不可变拷贝, 拷贝出来不可变
            NSMutableString *mStr2 = [mStr1 copy];
            NSLog(@"mStr2:%p", mStr2);
            NSLog(@"%lu", mStr1.retainCount);//1

      copy: 不可变拷贝, 拷贝出来不可变

            对不可变的数据类型, copy是浅拷贝

            对可变的数据类型, copy是深拷贝

     mutableCopy: 可变拷贝, 拷贝出来是可变的

            对不可变数据类型可变数据类型, mutableCopy都是深拷贝

            NSMutableString *mStr3 = [mStr1 mutableCopy];
            NSLog(@"%@", mStr3);
            [mStr3 setString:@"真帅"];
            NSLog(@"%@", mStr3);       
            NSString *tempName = [[NSString alloc] initWithFormat:@"无敌"];
            Student *tempStu = [[Student alloc] initWithName:tempName age:18 gender:@""];
            NSLog(@"%@", tempStu.name);      
            [tempName release];
            NSLog(@"%@", tempStu.name);

    通过便利构造器创建的对象, 不需要释放

            Student *s = [Student studentWithName:@"小明" age:18 gender:@""];
            NSLog(@"%@", s);

      集合中的内存管理

            1.集合会对放入到集合中的对象, 做引用计数+1的操作

            2.当对象从集合移除时, 做引用计数-1操作

            3.当集合释放时, 会对集合中的对象依次执行引用计数-1的操作 

            Student *s1 = [[Student alloc] initWithName:@"小强" age:18 gender:@""];
            Student *s2 = [[Student alloc] initWithName:@"小强" age:18 gender:@""];
            Student *s3 = [[Student alloc] initWithName:@"小强" age:18 gender:@""];
            NSMutableArray *array = [NSMutableArray arrayWithObjects:s1, s2, s3, nil];
            [s1 release];
            [s2 release];
            [s3 release];
            NSLog(@"%@", array);

     保留环(retainCycle): 两个对象相互保留对方, 导致这两个对象都无法得到释放

    解决方案: 打破环状结构

    Man.h
    #import <Foundation/Foundation.h>
    @class Woman;
    @interface Man : NSObject
    @property (nonatomic, assign) Woman *wife;
    //代理delegate写成属性, 修饰词用assign, 为了避免出现保留环
    //@property (nonatomic, assign) id<BaoMu> delegate;
    @end
    Man.m
    #import "Man.h"
    #import "Woman.h"
    @implementation Man
    - (void)dealloc {
        NSLog(@"男人释放了");
        [super dealloc];
    }
    @end
    Woman.h
    #import <Foundation/Foundation.h>
    @class Man;
    @interface Woman : NSObject
    @property (nonatomic, retain) Man *husband;
    @end
    Woman.m
    #import "Woman.h"
    #import "Man.h"
    @implementation Woman
    - (void)dealloc {
        NSLog(@"女人释放了");
        [_husband release];
        [super dealloc];
    }
    @end
    main.m
            Man *man = [[Man alloc] init];
            Woman *woman = [[Woman alloc] init];
            man.wife = woman;
            woman.husband = man;      
            [man release];
            [woman release];
            
    The one who wants to wear a crown must bear the weight!
  • 相关阅读:
    JS防止刷新,后退,关闭
    IIS日志-网站运维的好帮手
    未能加载文件或程序集“XXX”或它的某一个依赖项。磁盘空间不足---解决方案
    NOPI导出标准格式Excel
    DRBD+Heartbeat+Mysql高可用环境部署
    LVS三种包转发模型调度算法
    nagios环境部署(rhel6.5)
    关于nagios监控
    关于memcached原理及安装部署
    PHP5.4.36 RHEL6.5 源码编译安装
  • 原文地址:https://www.cnblogs.com/OrangesChen/p/4875761.html
Copyright © 2011-2022 走看看