码迷,mamicode.com
首页 > 其他好文 > 详细

内存管理高级

时间:2015-10-13 21:15:04      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

内存管理高级

内存管理高级:

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];
        

 

内存管理高级

标签:

原文地址:http://www.cnblogs.com/OrangesChen/p/4875761.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!