一、看MutableArray中的addObject之后的retainCount
Dog.h
#import <Foundation/Foundation.h> @interface Dog : NSObject { int _ID; } @property (assign) int ID; @endDog.m
#import "Dog.h" @implementation Dog @synthesize ID = _ID; //重写该方法,该方法自动会调用 -(void)dealloc{ NSLog(@"dog id %d is dealloc", _ID); [super dealloc]; } @end
main.m
#import <Foundation/Foundation.h> #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { NSMutableArray * array = [[NSMutableArray alloc] init]; for(int x = 0; x <5; x++){ Dog * d = [[Dog alloc] init]; [d setID: x]; NSLog(@"dog retainCount is %ld", [d retainCount]); [array addObject:d]; NSLog(@"dog retainCount2 is %ld", [d retainCount]); [d release]; } [array release]; } return 0; }输出结果:
2015-10-02 19:11:18.605 内存管理-MyArray[1770:59076] dog retainCount is 1 2015-10-02 19:11:18.606 内存管理-MyArray[1770:59076] dog retainCount2 is 2 2015-10-02 19:11:18.606 内存管理-MyArray[1770:59076] dog retainCount is 1 2015-10-02 19:11:18.606 内存管理-MyArray[1770:59076] dog retainCount2 is 2 2015-10-02 19:11:18.607 内存管理-MyArray[1770:59076] dog retainCount is 1 2015-10-02 19:11:18.607 内存管理-MyArray[1770:59076] dog retainCount2 is 2 2015-10-02 19:11:18.607 内存管理-MyArray[1770:59076] dog retainCount is 1 2015-10-02 19:11:18.607 内存管理-MyArray[1770:59076] dog retainCount2 is 2 2015-10-02 19:11:18.608 内存管理-MyArray[1770:59076] dog retainCount is 1 2015-10-02 19:11:18.608 内存管理-MyArray[1770:59076] dog retainCount2 is 2 2015-10-02 19:11:18.608 内存管理-MyArray[1770:59076] dog id 0 is dealloc 2015-10-02 19:11:18.608 内存管理-MyArray[1770:59076] dog id 1 is dealloc 2015-10-02 19:11:18.608 内存管理-MyArray[1770:59076] dog id 2 is dealloc 2015-10-02 19:11:18.608 内存管理-MyArray[1770:59076] dog id 3 is dealloc 2015-10-02 19:11:18.609 内存管理-MyArray[1770:59076] dog id 4 is dealloc Program ended with exit code: 0分析:
for循环四次,每次都进行相同的操作,目的是在数组中添加一个dog对象。
每次创建一个dog对象,retainCount=1,对象被引用次数为1,也就是自身保留,不被释放;
然后使用addObject方法,将对象添加到数组中,该对象的引用次数为2,除了自身之外,还被数组保留;
然后[d release],使得retainCount=1, 自身保留引用被删除,该对象只被数组拥有。
[array release],先释放数组中的dog对象,数组然后才被释放。
二、使用自定义数组分析addObject函数到底进行了操作
在上面的例子中,调用addObject方法后,retainCount就会+1,那其中到底进行了什么操作呢?
下面自己创建一个简单的数组类,来模拟其中的操作
MyArray.h
#import <Foundation/Foundation.h> //创建一个简易版的数组来分析addObject内部的操作。 @interface MyArray : NSObject { NSUInteger _count; //数组元素个数 id _objs[512]; //创建一个512个元素的数组,大小4x512字节 } @property (assign, readonly)NSUInteger count; -(void)addObject: (id)object; -(id)objectAtIndex: (NSUInteger)index; -(void)removeObjectAtIndex: (NSUInteger)index; -(void)removeAll; @endMyArray.m
#import "MyArray.h" @implementation MyArray @synthesize count = _count; -(id) init{ self = [super init]; if(self){ _count = 0; } return self; } -(void)addObject:(id)object{ if(_count > 512){ return; } _objs[_count] = [object retain]; _count++; //这里必须retain一次。因为如果外部调用了该方法,然后又调用了release,那么这里存的就是一个野指针。 } -(id)objectAtIndex:(NSUInteger)index{ return _objs[index]; } -(void)removeObjectAtIndex:(NSUInteger)index{ id obj = _objs[index]; [obj release]; //因为添加元素的时候有retain一次,这里必须release _objs[index] = nil; } -(void)removeAll{ for(int i = 0; i<_count; i++){ [self removeObjectAtIndex: i]; } } -(void)dealloc{ NSLog(@"before remove all"); [self removeAll]; NSLog(@"after remove all"); [super dealloc]; } @endmain.m
#import <Foundation/Foundation.h> #import "Dog.h" #import "MyArray.h" int main(int argc, const char * argv[]) { @autoreleasepool { #if 0 NSMutableArray * array = [[NSMutableArray alloc] init]; for(int x = 0; x <5; x++){ Dog * d = [[Dog alloc] init]; [d setID: x]; NSLog(@"dog retainCount is %ld", [d retainCount]); [array addObject:d]; NSLog(@"dog retainCount2 is %ld", [d retainCount]); [d release]; } [array release]; #endif MyArray * array = [[MyArray alloc] init]; for(int x = 0 ; x< 5; x++){ Dog * d = [[Dog alloc] init]; [d setID:x]; NSLog(@"dog retainCount is %ld", [d retainCount]); [array addObject:d]; NSLog(@"dog retainCount2 is %ld", [d retainCount]); [d release]; } [array release]; } return 0; }
查看输出结果:
2015-10-02 19:43:03.291 内存管理-MyArray[2297:69892] dog retainCount is 1 2015-10-02 19:43:03.293 内存管理-MyArray[2297:69892] dog retainCount2 is 2 2015-10-02 19:43:03.293 内存管理-MyArray[2297:69892] dog retainCount is 1 2015-10-02 19:43:03.293 内存管理-MyArray[2297:69892] dog retainCount2 is 2 2015-10-02 19:43:03.293 内存管理-MyArray[2297:69892] dog retainCount is 1 2015-10-02 19:43:03.293 内存管理-MyArray[2297:69892] dog retainCount2 is 2 2015-10-02 19:43:03.294 内存管理-MyArray[2297:69892] dog retainCount is 1 2015-10-02 19:43:03.294 内存管理-MyArray[2297:69892] dog retainCount2 is 2 2015-10-02 19:43:03.294 内存管理-MyArray[2297:69892] dog retainCount is 1 2015-10-02 19:43:03.294 内存管理-MyArray[2297:69892] dog retainCount2 is 2 2015-10-02 19:43:03.295 内存管理-MyArray[2297:69892] before remove all 2015-10-02 19:43:03.295 内存管理-MyArray[2297:69892] dog id 0 is dealloc 2015-10-02 19:43:03.295 内存管理-MyArray[2297:69892] dog id 1 is dealloc 2015-10-02 19:43:03.295 内存管理-MyArray[2297:69892] dog id 2 is dealloc 2015-10-02 19:43:03.295 内存管理-MyArray[2297:69892] dog id 3 is dealloc 2015-10-02 19:43:03.296 内存管理-MyArray[2297:69892] dog id 4 is dealloc 2015-10-02 19:43:03.296 内存管理-MyArray[2297:69892] after remove all Program ended with exit code: 0
@诗未冷学习博客