首页 新闻 会员 周边

OC内存到底应该怎样理解?

0
悬赏园豆:50 [待解决问题]

初学内存管理,写了一个程序如下:

 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之前之后呢?

类的属性为一个对象的时候,内存到底是怎么分配的?

 
 
刘lady的主页 刘lady | 初学一级 | 园豆:152
提问于:2015-04-26 21:45
< >
分享
所有回答(1)
0

如果对一个对象使用了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内存管理的黄金法则

应有梦 | 园豆:205 (菜鸟二级) | 2015-08-12 10:48

嗯,谢谢,可是当dog1已经dealloc之后,还能在P1的dealloc里面继续打印_dog的计数器是1,_dog指向dog1对象的,dog1都dealloc,应该已经被释放,那么_dog的计数器应该已经是0了啊

支持(0) 反对(0) 刘lady | 园豆:152 (初学一级) | 2015-08-12 10:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册