在以前的一片文章中,咱们介绍了数组操做对象的时候引用问题以及自动释放池的概念:java
http://blog.csdn.net/jiangwei0910410003/article/details/41926183数组
今天咱们继续来看一下引用计数中一个痛疼的问题:循环引用测试
关于循环引用的问题,这里就不作太多解释了,就是多个对象之间相互引用,造成环状。atom
来看一个具体的例子:spa
Dog类和Person类之间相互引用.net
Dog.hcode
// // 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 // 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]; } @endDog类中有一个Person类型的属性
Person.h对象
// // 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 // 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]; } @endPerson类中有Dog类型的属性
看一下测试代码blog
main.mip
// // 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
总结
循环引用是对象销毁的时候遇到的最大的一个问题,在java中,垃圾回收器也会遇到这样的问题,因此就不采用引用计数法去管理对象了,而是另外的一种方式去管理,能够参考:http://blog.csdn.net/jiangwei0910410003/article/details/40709457