码迷,mamicode.com
首页 > 其他好文 > 详细

浅谈 关于ARC循环引用得问题

时间:2014-11-18 13:08:57      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   color   ar   os   sp   for   strong   

这段时间在研究关于ARC得循环引用导致变量不能释放,在此先介绍一本书英文书:

《Pro Multithreading and Memory Management for iOS and OS X with ARC, Grand Central Dispatch, and Blocks》

(《iOS与OS X多线程和内存管理》)

建议读英文原版,中文版看的我稀里糊涂的,后来被迫去看原版.这本书介绍了关于ARC的自动引用机制,这里的机制类似:当C语言的局部变量离开他的作用域之后就会被清除,这里的ARC也类似是这样的原理,如下面的代码一样,当离开{}之后obj会被nil。默认id是强指针

{
/*
* You create an object and have ownership. */
id __strong obj = [[NSObject alloc] init];
/*
* The variable obj is qualified with __strong.
* Which means, it has ownership of the object. */
}
/*
* Leaving the scope of variable obj, its strong reference disappears.
* The object is released automatically.
* Because no one has ownership, the object is disposed of.
*/

 

不过有一种情况会导致在{}内的变量再离开作用域之后不会释放,这就是循环引用,下面我先贴一份没有循环引用的代码

//Test Class
@interface Test : NSObject
@property (nonatomic) id obj;
- (void) setObj:(id)obj;
@end
@implementation Test
- (void) setObj:(id)obj{
    _obj = obj;
}
@end

//Use Test Class
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    id test0 = [[Test alloc]init];
    id test1 = [[Test alloc]init];

    self.t0 = test0;
    self.t1 = test1;
}

- (void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    NSLog(@"test0 is %p",self.t0);
    NSLog(@"test1 is %p",self.t1);
    NSLog(@"test0 obj is %p",self.t0.obj);
    NSLog(@"test1 obj is %p",self.t1.obj);
    NSLog(@"viewDidApperar!");
}
/*  这里的输出结果:
2014-11-18 11:39:31.654 circular[27065:60b] test0 is (null)
2014-11-18 11:39:31.654 circular[27065:60b] test1 is (null)
2014-11-18 11:39:31.655 circular[27065:60b] test0 obj is (null)
2014-11-18 11:39:31.655 circular[27065:60b] test1 obj is (null)
2014-11-18 11:39:31.655 circular[27065:60b] viewDidApperar!
    */

 

现在我贴一下存在循环引用的代码,这个时候局部变量的强指针相互引用,这里我们可以看见Test0的obj指向Test1,而Test1的obj指向Test0,导致释放不了.

//Test Class
@interface Test : NSObject
@property (nonatomic) id obj;
- (void) setObj:(id)obj;
@end
@implementation Test
- (void) setObj:(id)obj{
    _obj = obj;
}
@end

//Use Test Class
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    id test0 = [[Test alloc]init];
    id test1 = [[Test alloc]init];
    [test0 setObj:test1];
    [test1 setObj:test0];    
    self.t0 = test0;
    self.t1 = test1;
}

- (void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    NSLog(@"test0 is %p",self.t0);
    NSLog(@"test1 is %p",self.t1);
    NSLog(@"test0 obj is %p",self.t0.obj);
    NSLog(@"test1 obj is %p",self.t1.obj);
    NSLog(@"viewDidApperar!");
}

/*这里的输出结果:
2014-11-18 11:42:35.555 circular[27654:60b] test0 is <Test: 0x8c8fe20>
2014-11-18 11:42:35.556 circular[27654:60b] test1 is <Test: 0x8cf7c20>
2014-11-18 11:42:35.556 circular[27654:60b] test0 obj is <Test: 0x8cf7c20>
2014-11-18 11:42:35.556 circular[27654:60b] test1 obj is <Test: 0x8c8fe20>
2014-11-18 11:42:35.558 circular[27654:60b] viewDidApperar!
*/

 一般的解决办法就是weak obj,代码如下:

//Test Class
@interface Test : NSObject
@property (nonatomic,weak) id obj;
- (void) setObj:(id)obj;
@end
@implementation Test
- (void) setObj:(id)obj{
    _obj = obj;
}
@end

//Use Test Class
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    id test0 = [[Test alloc]init];
    id test1 = [[Test alloc]init];
    [test0 setObj:test1];
    [test1 setObj:test0];    
    self.t0 = test0;
    self.t1 = test1;
}

- (void) viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

    NSLog(@"test0 is %p",self.t0);
    NSLog(@"test1 is %p",self.t1);
    NSLog(@"test0 obj is %p",self.t0.obj);
    NSLog(@"test1 obj is %p",self.t1.obj);
    NSLog(@"viewDidApperar!");
}

/*这里的输出结果:
2014-11-18 11:46:19.803 circular[28360:60b] test0 is (null)
2014-11-18 11:46:19.804 circular[28360:60b] test1 is (null)
2014-11-18 11:46:19.804 circular[28360:60b] test0 obj is (null)
2014-11-18 11:46:19.805 circular[28360:60b] test1 obj is (null)
2014-11-18 11:46:19.805 circular[28360:60b] viewDidApperar!
*/

 

浅谈 关于ARC循环引用得问题

标签:style   blog   io   color   ar   os   sp   for   strong   

原文地址:http://www.cnblogs.com/zuopeng/p/4105356.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!