zoukankan      html  css  js  c++  java
  • Objectc 内存一些事

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

  • 相关阅读:
    创业团队的狼性管理:慈不掌兵 义不聚财
    爱德华·斯诺登
    塞班岛
    大兴雷克萨斯深度剖析2013款LS460L_深圳大兴雷克萨斯_太平洋汽车网
    金字塔底端_百度百科
    左立_百度百科
    志大才疏_百度百科
    JS~json日期格式化
    MVVM架构~knockoutjs系列之从Knockout.Validation.js源码中学习它的用法
    JS~重写alter与confirm,让它们变成fancybox风格
  • 原文地址:https://www.cnblogs.com/GnagWang/p/2248134.html
Copyright © 2011-2022 走看看