

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 有什么影响?