Object-c 内存一些事

View Code
 1 @interface ClassC : NSObject {
2 @private
3
4 }
5 @end
6
7 @implementation ClassC
8
9 -(void) dealloc
10 {
11 [super dealloc];
12
13 }
14 @end
15
16 @interface ClassB : NSObject {
17 @private
18 ClassC * class_c;
19 }
20
21 @property(nonatomic, retain) ClassC * classc;
22 @end
23
24 @implementation ClassB
25
26 @synthesize classc = class_c;
27 -(id) init
28 {
29 if (self = [super init]) {
30 class_c = [[ClassC alloc] init];
31 }
32
33 return self;
34 }
35
36 -(void) dealloc
37 {
38 [super dealloc];
39 self.classc = Nil;
40 // [class_c release];
41 }
42 @end

调用如下:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    ClassB * b = [[ClassB alloc] init];
    [b release];
   [pool release];
}

 

根据调试的结果,在ClassB的dealloc中使用:self.classc = Nil;也可以执行到ClassC的dealloc方法, 说明使用self.classc = Nil & self.classc = nil & [class_c release]的效果都是一样的。

如果在ClassB的init方法不去初始化 class_c 执行[class_c release] 也不会出错,因为ios中向一个空的对象发送消息是没有问题的。

 

在ClaasB中

-(void) dealloc
{
    [super dealloc];
//    self.classc = nil;
    [class_c release];
//    class_c = nil;
    
    [class_c release];
    class_c = nil;

}

 也不会有问题。

 

但是,在ClassB中如下就出问题了

@interface ClassB : NSObject {
@private
    ClassC * class_c;
    ClassC * class_c1;
    ClassC * class_c2;
}

@property(nonatomic, retain) ClassC * classc;
@property(nonatomic, retain) ClassC * classc1;
@property(nonatomic, retain) ClassC * classc2;

-(void) test;
@end

@implementation ClassB

@synthesize classc = class_c;
@synthesize classc1 = class_c1;
@synthesize classc2 = class_c2;
-(id) init
{
    if (self = [super init]) {
        class_c = [[ClassC alloc] init];
        class_c1 = [[ClassC alloc] init];
        class_c2 = [[ClassC alloc] init];
    }
    
    return self;
}

-(void) test
{
    self.classc = self.classc1;
    self.classc1 = self.classc2;
    self.classc2 = nil;
    
    
}
-(void) dealloc
{
    [super dealloc];
    self.classc = Nil;   // = nil 也是一样的
    self.classc1 = Nil;
    self.classc2 = Nil;
//    [class_c release];
//    class_c = nil;
//    
//    [class_c1 release];
//    class_c1 = nil;
//    
//    [class_c2 release];
//    class_c2 = nil;
    

}
@end

 这样在[b release];的时候 就报了 EXC_BAD_ACCESS错误, 好换种写法:

-(void) dealloc
{
    [super dealloc];
//    self.classc = nil;
//    self.classc1 = nil;
//    self.classc2 = nil;
    [class_c release];
    class_c = nil;
    
    [class_c1 release];
    class_c1 = nil;
    
    [class_c2 release];
    class_c2 = nil;
    

}

 这次就正确了,没有任何错误,得到结论1:在释放对象的时候,使用 [xxx release]; 尽量不要使用self.xxxx = nil这种方式

此时多调用 几次

    [b test];
    [b test];
    [b test];
    [b test];

也没有错误,        再试下不初始化 三个class_c 也是没有问题的。


但是:我们之前也有得到一个结论:说明使用self.classc = Nil & self.classc = nil & [class_c release]的效果都是一样的。

 那这两个结论不是矛盾的么? 其中的原因到底是为什么?我接着做了如下尝试:

@interface ClassB : NSObject {
@private
    ClassC * class_c;
    ClassC * class_c1;
    ClassC * class_c2;
}

@property(nonatomic, retain) ClassC * classc;
@property(nonatomic, retain) ClassC * classc1;
@property(nonatomic, retain) ClassC * classc2;

-(void) test;
@end

@implementation ClassB

@synthesize classc = class_c;
@synthesize classc1 = class_c1;
@synthesize classc2 = class_c2;
-(id) init
{
    if (self = [super init]) {
        class_c = [[ClassC alloc] init];
        class_c1 = [[ClassC alloc] init];
        class_c2 = [[ClassC alloc] init];
    }
    
    return self;
}

-(void) test
{
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
    self.classc = self.classc1;
    
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
    self.classc1 = self.classc2;
    
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
    
    self.classc2 = nil;
    
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
}

-(void) dealloc
{
    [super dealloc];  
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
    self.classc = nil;
    
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
    self.classc1 = nil;
    
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);    
    self.classc2 = nil;
    
    
//    [class_c release];
//    class_c = nil;
//    
//    [class_c1 release];
//    class_c1 = nil;
//    
//    [class_c2 release];
//    class_c2 = nil;
    

}

 这样结果也是一样的,很崩溃,在ClassB的dealloc方法里面,没关系再试试,我重新尝试了一下

-(void) dealloc
{
     
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
    self.classc = nil;
    
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);
    self.classc1 = nil;
    
    NSLog(@"class_c is :%d", class_c.retainCount);
    NSLog(@"class_c1 is :%d", class_c1.retainCount);
    NSLog(@"class_c2 is :%d", class_c2.retainCount);    
    self.classc2 = nil;
    [super dealloc];  
}

 这时候竟然神一样的没有问题了, 不同的地方就是[ super dealloc ] 这句,放到后面就正确了,再做如下两个实验:

-(void) dealloc
{

    [class_c release];
    class_c = nil;
    
    [class_c1 release];
    class_c1 = nil;
    
    [class_c2 release];
    class_c2 = nil;
    [super dealloc];  

}

 

-(void) dealloc
{
    
    [super dealloc];  
    
    [class_c release];
    class_c = nil;
    
    [class_c1 release];
    class_c1 = nil;
    
    [class_c2 release];
    class_c2 = nil;
    

}

 这两种都是可以正确执行的,没有问题,那么问题的核心就在 [super delloc] 到底对 sekf.xxxx = nil 有什么影响?

 

posted @ 2011-11-14 11:42  Gang.Wang  阅读(554)  评论(0编辑  收藏  举报