iOS笔记 - 循环引用


循环引用

1 - 代码示例:以 retain 特性为例,造成该问题的原因就是双方都引用了彼此,且都使用了 retain 修饰属性

// - main.m

 1 #import 
 2 #import "People.h"
 3 #import "Animal.h"
 4 int main(int argc, const char * argv[]) {
 5     
 6  7 //    Animal *a = [[Animal alloc] init];// 1
 8 //    People *p = [[People alloc] init];// 1
 9 //    a.per = p;// +1
10 //    p.cat = a;// +1
11 //    NSLog(@"%ld",a.retainCount);// 2
12 //    NSLog(@"%ld",p.retainCount);// 2
13 //    [a release];// 1
14 //    [p release];// 1
15 //    // 造成问题:彼此谁也释放不掉谁
16     
17     //解决方案:在任意一方,把 retain 改换成 assign 即可
18     Animal *a = [[Animal alloc] init];// 1
19     People *p = [[People alloc] init];// 1
20     a.per = p;// P +1
21     p.cat = a;// 1
22     NSLog(@"%ld",a.retainCount);// 1
23     NSLog(@"%ld",p.retainCount);// 2
24     
25     [p release];// p -1
26     [a release];// 触发 dealloc
27     
28     return 0;
29 }

// - Animal.h

1 @class People;
2 #import 
3 
4 @interface Animal : NSObject
5 
6 @property(nonatomic,retain)People *per;
7 
8 @end

// - Animal.m

 1 #import "Animal.h"
 2 
 3 @implementation Animal
 4 -(void)dealloc{
 5     
 6     NSLog(@"Animal 触发");
 7     self.per = nil;
 8     [super dealloc];
 9 }
10 @end

// - People.h

1 @class Animal;
2 #import 
3 
4 @interface People : NSObject
5 
6 //@property(nonatomic,retain)Animal*cat;
7 @property(nonatomic,assign)Animal*cat;// 打破循环引用即可
8 
9 @end

// - People.m

 1 #import "People.h"
 2 
 3 @implementation People
 4 -(void)dealloc{
 5     
 6     NSLog(@"People 触发");
 7     self.cat = nil;
 8     [super dealloc];
 9 }
10 
11 @end