内存管理高级(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!