如果我們用對(duì)象A的屬性(strong修飾)去指向一個(gè)objc對(duì)象B涡扼。那么如果對(duì)象A沒(méi)有被釋放對(duì)象B永遠(yuǎn)不會(huì)被釋放。如果對(duì)象B是一個(gè)view當(dāng)我們已經(jīng)把B添加到視圖上的時(shí)候萄凤。有些情況下可能希望提前釋放掉對(duì)象B施绎。這種情況下我們可以使用weak修飾符指向來(lái)達(dá)到可以提前釋放的效果。
代碼如下
@interface ViewController ()
//使用weak修飾weakView
@property (nonatomic, weak) UIView *weakView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.weakView = [[UIView alloc]initWithFrame:CGRectMake(0, 20, 300, 40)];
_weakView.backgroundColor = [UIColor redColor];
[self.view addSubview:_weakView];
}
通過(guò)結(jié)果發(fā)現(xiàn)weakView并沒(méi)有強(qiáng)引用新創(chuàng)建的View节榜。新創(chuàng)建的View唄創(chuàng)建出來(lái)之后直接被釋放了。這種方法并不可取别智。
我們更換一種方法
@interface ViewController ()
@property (nonatomic, weak) UIView *weakView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//創(chuàng)建一個(gè)cacheView指向新創(chuàng)建的view
UIView *cacheView = [[UIView alloc]initWithFrame:CGRectMake(0, 20, 300, 40)];
//通過(guò)一個(gè)weak修飾的屬性指向cacheView
self.weakView = cacheView;
_weakView.backgroundColor = [UIColor redColor];
[self.view addSubview:_weakView];
}
發(fā)現(xiàn)這種可以保證在屬性指向過(guò)程中不會(huì)強(qiáng)引用cacheView宗苍,又能保證可以在必要的時(shí)候提前釋放掉view
驗(yàn)證自動(dòng)釋放池外是否可以通過(guò)weak指針正常獲取到cacheView
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"%@",self.weakView);
}
控制臺(tái)輸出為:
2018-02-01 15:08:29.019353+0800 WeakView[1806:133550] <UIView: 0x7f91a1d09f60; frame = (0 20; 300 40); layer = <CALayer: 0x604000037ca0>>
原理分析:
1.現(xiàn)在的絕大多數(shù)開發(fā)都是使用ARC來(lái)進(jìn)行開發(fā)。因?yàn)槭褂昧俗詣?dòng)釋放池。我們?cè)谧詣?dòng)釋放池中創(chuàng)建的對(duì)象默認(rèn)都是使用strong修飾的讳窟。但是會(huì)在自動(dòng)釋放池外autorealease掉让歼。如果直接用weak屬性來(lái)存儲(chǔ)新創(chuàng)建的view。那么會(huì)直接使用weak對(duì)象來(lái)指向丽啡。直接被釋放掉了谋右。
2.我們先用一個(gè)臨時(shí)指針指向,通過(guò)[self.view addSubview:_weakView]這句代碼會(huì)對(duì)weakView進(jìn)行強(qiáng)引用补箍。然后用weak指針指向改执。這樣weakView既不會(huì)被自身強(qiáng)引用。同時(shí)也可以通過(guò)weak指針來(lái)獲取對(duì)象坑雅。