标签:
2.对什么进行管理:
#import "Student.h" @implementation Student - (void)dealloc { NSLog(@"student对象被释放"); [super dealloc]; } @end
main.m文件如下:
#import <Foundation/Foundation.h> #import "Student.h" int main(int argc, const char * argv[]) { //创建student对象 //alloc创建对象后,对象的引用计数器为1 Student* student = [[Student alloc]init]; //查看此时的对象引用计数器是多少 NSLog(@"%ld",[student retainCount]); return 0; }
运行结果如下:
2015-08-19 14:48:26.320 01-引用计数器的基本使用[649:41159] 1
当我们使用release对引用计数器减1之后:
main.m文件如下:
#import <Foundation/Foundation.h> #import "Student.h" int main(int argc, const char * argv[]) { //创建student对象 //alloc创建对象后,对象的引用计数器为1 Student* student = [[Student alloc]init]; [student release]; return 0; }
运行结果如下:
2015-08-19 14:50:48.079 01-引用计数器的基本使用[659:42849] student对象被释放
我们看到引用计数器为0,对象被销毁了。好,我们再试着修改main.m
#import <Foundation/Foundation.h> #import "Student.h" int main(int argc, const char * argv[]) { //创建student对象 //alloc创建对象后,对象的引用计数器为1 Student* student = [[Student alloc]init]; //对引用计数器加1 [student retain]; NSLog(@"%ld",[student retainCount]); return 0; }
运行结果:
2015-08-19 14:54:30.940 01-引用计数器的基本使用[677:45062] 1 2015-08-19 14:54:30.941 01-引用计数器的基本使用[677:45062] 2
#import <Foundation/Foundation.h> #import "Book.h" @interface Student : NSObject { Book* _book; } //set方法 -(void)setBook:(Book*)book; //get方法 -(Book*)book; @end
student.m文件如下:
#import "Student.h" @implementation Student //set方法实现 -(void)setBook:(Book *)book { _book = book; } //get方法实现 -(Book*)book { return _book; } //dealloc方法 - (void)dealloc { NSLog(@"学生对象被释放"); [super dealloc]; } @end
Book.h不变Book.m文件如下:
#import "Book.h" @implementation Book - (void)dealloc { NSLog(@"书被释放"); [super dealloc]; } @end
运行结果如下:
2015-08-19 16:46:03.951 02-类内部的内存管理1[925:97891] 学生对象被释放 2015-08-19 16:46:03.952 02-类内部的内存管理1[925:97891] 书被释放
我们发现book和student都被释放了,这是为什么呢?书本明明被引用了两次(alloc和setBook)。release一次。但也被释放了。我们观察发现,这是因为student没有对book做retain操作。所以,我们在student的set方法中,补充上retain操作。
student.m文件修改成下面这样:
#import "Student.h" @implementation Student //set方法实现 -(void)setBook:(Book *)book { _book = [book retain]; } //get方法实现 -(Book*)book { return _book; } //dealloc方法 - (void)dealloc { NSLog(@"学生对象被释放"); [super dealloc]; } @end
运行结果如下:
2015-08-19 16:49:41.920 02-类内部的内存管理1[936:99847] 学生对象被释放
看似正确了,但总觉的哪里不对,是的,相信你的直觉,我们一起来画图看看。
#import "Student.h" @implementation Student //set方法实现 -(void)setBook:(Book *)book { _book = [book retain]; } //get方法实现 -(Book*)book { return _book; } //dealloc方法 - (void)dealloc { NSLog(@"学生对象被释放"); [_book release]; [super dealloc]; } @end
#import <Foundation/Foundation.h> #import "Book.h" @interface Student : NSObject { int _age; Book* _book; } //book的set和get方法 -(void)setBook:(Book*)book; -(Book*)book; //age的get和set方法 -(void)setAge:(int)age; -(int)age; @end
student.m代码如下:
#import "Student.h" @implementation Student -(void)setBook:(Book *)book { _book = [book retain]; } -(Book*)book { return _book; } -(void)setAge:(int)age { //基本数据类型,不必做内存管理 _age = age; } -(int)age { return _age; } - (void)dealloc { [_book release]; NSLog(@"学生对象被销毁了"); [super dealloc]; } @end
book.h代码如下:
#import <Foundation/Foundation.h> @interface Book : NSObject { //页数 int _page; } //页数的set和get方法 -(void)setPage:(int)page; -(int)page; @end
book.m代码如下:
#import "Book.h" @implementation Book -(void)setPage:(int)page { _page = page; } -(int)page { return _page; } - (void)dealloc { NSLog(@"书被销毁了"); [super dealloc]; } @end
运行结果:
2015-08-19 19:30:07.608 03-Set方法内存管理[1231:149504] 学生对象被销毁了 2015-08-19 19:30:07.609 03-Set方法内存管理[1231:149504] 书被销毁了
看似很完美是吧,一本书,一个学生,书alloc一次,ratain一次。release两次。学生alloc一次。release一次。完全没有问题。别着急,看看我将主函数改成这样会如何:
main.m:
#import <Foundation/Foundation.h> #include "Student.h" #include "Book.h" int main(int argc, const char * argv[]) { Student* s = [[Student alloc]init]; Book* b = [[Book alloc]init]; //将书给学生 [s setBook:b]; //又创建了一本书b1 Book* b1 = [[Book alloc] init]; //学生将书b换成了b1 [s setBook:b1]; //alloc后要release //新创建的b1 也做了release [s release]; [b release]; [b1 release]; return 0; }
以上代码要表达的意思很简单,就是这个学生换了一本新书:
运行结果:
2015-08-19 19:38:10.378 03-Set方法内存管理[1269:154354] 学生对象被销毁了 2015-08-19 19:38:10.379 03-Set方法内存管理[1269:154354] 书被销毁了
明明有两本书,却只被销毁了一本。这是什么问题导致的呢?观察代码后,我们发现。我们在给学生换书的时候调用了set方法。而set方法中仅仅对新书做了retain操作,并没有对旧书做release操作。(以前对旧书做release操作,是因为Student对象销毁的时候在dealloc方法中做的,但现在是换书,并没有销毁student对象)。所以,我们要在set方法中判断新书旧书,对新书retain,对旧书release,代码如下:
重新修改后的set方法:
@implementation Student -(void)setBook:(Book *)book { //如果新书不等于旧书,说明是换书 if (_book !=book) { //对旧书做release [_book release]; _book = [book retain]; } }
运行结果如下:
2015-08-19 19:49:28.347 03-Set方法内存管理[1288:157711] 学生对象被销毁了 2015-08-19 19:49:28.348 03-Set方法内存管理[1288:157711] 书被销毁了 2015-08-19 19:49:28.348 03-Set方法内存管理[1288:157711] 书被销毁了
金星老师:完美!!!!
10.内存管理代码规范
-(void)setName:(NSString*)name { _name_name; }
-(void)setName:(NSString*)name { if(_name != name) { [_name release]; _name = [name retain]; } }
@Property(ratain) NSString* name
标签:
原文地址:http://www.cnblogs.com/hellomeng/p/4743826.html