初学内存管理,写了一个程序如下:
1 Dog.h 2 3 @interface dog : NSObject { 4 NSString *_name; 5 } 6 @proprety(copy) NSString *name; 7 8 @end 9 10 Dog.m 11 12 @implementation Dog 13 14 - (void)dealloc { 15 NSLog(@"dog dealloc"); 16 [super dealloc]; 17 } 18 19 @end
1 Preson.h 2 3 @class Dog; 4 5 @interface Preson : NSObject { 6 Dog *_dog; 7 NSString *_name; 8 } 9 @proprety(copy) NSString *name; 10 11 - (void)setDog:(Dog *)dog; 12 - (id)dog; 13 14 @end 15 16 Preson.m 17 18 #improt "Dog.h" 19 20 @implementation Preson 21 22 - (void)setDog:(Dog *)dog { 23 if (_dog != dog) { 24 [_dog release]; 25 _dog = [dog release]; 26 } 27 } 28 29 - (id)dog { 30 return _dog; 31 } 32 33 - (void) delalloc { 34 NSLog(@"%@ dealloc",self.name); 35 if (_dog != nil) { 36 [_dog release]; 37 NSLog(@"-------%@.retainCount = %ld",_dog.name,_dog.retainCount); 38 } 39 [super dealloc]; 40 } 41 42 @end
1 int main (int argc,const char *argv[]) { 2 Preson *p1 = [Preson alloc]init]; 3 [p1 setName:@"p1"]; 4 5 Dog *dog1 = [Dog alloc]init]; 6 [dog1 setName:@"black"]; 7 8 [p1 setDog:dog1]; 9 10 Preson *p2 = [Preson alloc]init]; 11 [p2 setName:@"p2"]; 12 13 [p2 setDog:dog1]; 14 15 NSLog(@"dog1.retainCount = %ld",dog1.retainCount); 16 17 [p2 release]; 18 [dog1 release]; 19 NSLog(@"release dog1 %@.retainCount = %ld,dog1.name,dog1.retainCount"): 20 [p1 release];
运行打印如下:
1 dog1.retainCount = 3 2 p2 dealloc 3 -------black.retainCount = 2 4 release dog1 black.retainCount = 1 5 p1 release 6 dog dealloc 7 -------black.retainCount = 1
问题:为什么dog1已经dealloc了,还能在P1的dealloc里面继续使用_dog,而且计数器还是1,_dog不是指向dog1对象的么?
因为调试发现p2 release之后即调用dealloc,进去后先运行第一条语句打印,然后dog就dealloc了,如果第一条打印语句在if语句块后面,则先dog dealloc,if语句块,最后打印语句
看到解释都说对象的计数器为0,系统自动回收内存,是在dealloc之前之后呢?
类的属性为一个对象的时候,内存到底是怎么分配的?
如果对一个对象使用了alloc、[mutable]copy、retain,那么你必须使用相应的release或者autorelease。
类型定义:
基本类型:任何C的类型,如:int、short、char、long、struct、enum、union等属于基本类型或者结构体;
内存管理对于C语言基本类型无效;
任何继承与NSObject类的对象都属于OC类型。
所有OC对象都有一个计数器,保留着当前被引用的数量。
内存管理对象:
OC的对象:凡是继承于NSObject;
每一个对象都有一个retainCount计数器。表示当前的被应用的计数。如果计数为0,那么就真正的释放这个对象。
alloc、retain、release函数:
1)alloc 函数是创建对象使用,创建完成后计数器为1;只用1次。
2)retain是对一个对象的计数器+1;可以调用多次。
3)release是对一个对象计数器-1;减到0对象就会从内存中释放。
增加对象计数器的三种方式:
1)当明确使用alloc方法来分配对象;
2)当明确使用copy[WithZone:]或者mutableCopy[WithZone:]来copy对象的时;
3)当明确使用retain消息。
这个就是OC内存管理的黄金法则
嗯,谢谢,可是当dog1已经dealloc之后,还能在P1的dealloc里面继续打印_dog的计数器是1,_dog指向dog1对象的,dog1都dealloc,应该已经被释放,那么_dog的计数器应该已经是0了啊