A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© zhou_xingyu 中级黑马   /  2015-8-3 08:37  /  451 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Dog类和Person类之间相互引用




Dog.h


[objc] view plaincopyprint?//   
//  Dog.h   
//  29_CyclePointer   
//   
//  Created by jiangwei on 14-10-13.   
//  Copyright (c) 2014年 jiangwei. All rights reserved.   
//   
  
#import <Foundation/Foundation.h>   
  
#import "Person.h"   
  
@interface Dog : NSObject  
  
//这里不用retain,如果使用retain的话,会形成循环引用   
@property(nonatomic,assign,readwrite) Person *person;  
  
- (void)dealloc;  
  
@end  

//
//  Dog.h
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Person.h"

@interface Dog : NSObject

//这里不用retain,如果使用retain的话,会形成循环引用
@property(nonatomic,assign,readwrite) Person *person;

- (void)dealloc;

@end




Dog.m

[objc] view plaincopyprint?//   
//  Dog.m   
//  29_CyclePointer   
//   
//  Created by jiangwei on 14-10-13.   
//  Copyright (c) 2014年 jiangwei. All rights reserved.   
//   
  
#import "Dog.h"   
  
@implementation Dog  
  
- (void)dealloc{  
    //[_person release];   
    NSLog(@"dog dealloc");  
    [super dealloc];  
}  
  
@end  

//
//  Dog.m
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import "Dog.h"

@implementation Dog

- (void)dealloc{
    //[_person release];
    NSLog(@"dog dealloc");
    [super dealloc];
}

@end
Dog类中有一个Person类型的属性




Person.h


[objc] view plaincopyprint?//   
//  Person.h   
//  29_CyclePointer   
//   
//  Created by jiangwei on 14-10-13.   
//  Copyright (c) 2014年 jiangwei. All rights reserved.   
//   
  
#import <Foundation/Foundation.h>   
  
@class Dog;  
  
@interface Person : NSObject  
  
@property(nonatomic,retain,readwrite) Dog *dog;  
  
- (void)dealloc;  
  
@end  

//
//  Person.h
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import <Foundation/Foundation.h>

@class Dog;

@interface Person : NSObject

@property(nonatomic,retain,readwrite) Dog *dog;

- (void)dealloc;

@end

Person.m


[objc] view plaincopyprint?//   
//  Person.m   
//  29_CyclePointer   
//   
//  Created by jiangwei on 14-10-13.   
//  Copyright (c) 2014年 jiangwei. All rights reserved.   
//   
  
#import "Person.h"   
  
#import "Dog.h"   
  
@implementation Person  
  
- (void)dealloc{  
    [_dog release];  
    NSLog(@"Person dealloc");  
    [super dealloc];  
}  
  
@end  

//
//  Person.m
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import "Person.h"

#import "Dog.h"

@implementation Person

- (void)dealloc{
    [_dog release];
    NSLog(@"Person dealloc");
    [super dealloc];
}

@end
Person类中有Dog类型的属性




看一下测试代码

main.m


[objc] view plaincopyprint?//   
//  main.m   
//  29_CyclePointer   
//   
//  Created by jiangwei on 14-10-13.   
//  Copyright (c) 2014年 jiangwei. All rights reserved.   
//   
  
#import <Foundation/Foundation.h>   
  
#import "Dog.h"   
#import "Person.h"   
  
//循环引用   
//是一个很麻烦的一件事,完全靠经验   
int main(int argc, const charchar * argv[]) {  
      
    Person *p = [[Person alloc] init];  
    Dog *dog = [[Dog alloc] init];  
      
    [p setDog:dog];//dog计数:2   
      
    [dog setPerson:p];//person计数:2   
      
    [p release]; //person计数:1   
    [dog release];//dog计数:1   
      
    //没有释放的原因是dealloc方法中没有被执行,里面的释放代码也就没执行了,dog和person各自在等待,形成环状了   
    //解决版本就是切断他们之间的联系   
    //@property中不使用retain,使用assgin   
      
    NSLog(@"is over");  
      
    return 0;  
}  

//
//  main.m
//  29_CyclePointer
//
//  Created by jiangwei on 14-10-13.
//  Copyright (c) 2014年 jiangwei. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "Dog.h"
#import "Person.h"

//循环引用
//是一个很麻烦的一件事,完全靠经验
int main(int argc, const char * argv[]) {
   
    Person *p = [[Person alloc] init];
    Dog *dog = [[Dog alloc] init];
   
    [p setDog:dog];//dog计数:2
   
    [dog setPerson:p];//person计数:2
   
    [p release]; //person计数:1
    [dog release];//dog计数:1
   
    //没有释放的原因是dealloc方法中没有被执行,里面的释放代码也就没执行了,dog和person各自在等待,形成环状了
    //解决版本就是切断他们之间的联系
    //@property中不使用retain,使用assgin
   
    NSLog(@"is over");
   
    return 0;
}
我们分别定义了一个Person对象和Dog对象,然后相互引用了,但是当我们调用他们的release方法的时候,这两个对象并没有被释放

原因很简单:


person和dog的相互引用了,当执行release方法的时候引用计数都还是1,所以就不会调用dealloc方法了

dealloc方法中没有被执行,里面的释放代码也就没执行了,dog和person各自在等待,形成环状了




解决的办法是:


切断他们之间的联系

在一方中定义属性的时候,@property中不使用retain,使用assgin

同时在dealloc方法中不再调用release方法了

上面的例子中,我们可以看到Dog类中就是使用assgin



1 个回复

倒序浏览
占一个,哈哈哈
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马