1.強引用
在ARC中修飾符是__strong,比如
__strong NSObject *obj;
不加修飾符的話默認都是__strong运悲。
2.弱引用
在ARC中修飾符是__weak乍构,比如
__weak NSObject *obj;
3.兩者區(qū)別
簡單點講的話旨袒,強引用持有對象瓣铣,而弱引用不持有對象炮叶。
下面看代碼詳解:
? ? __strong NSObject *obj1=[[NSObject alloc] init];
? ? __strong NSObject *obj2=obj1;
? ? NSLog(@"%@,%@",obj1,obj2);
? ? obj1=nil;
? ? NSLog(@"%@,%@",obj1,obj2);
? ? //輸出 :
? ? //<NSObject: 0x7fef53708b80>,<NSObject: 0x7fef53708b80>
? ? //(null),<NSObject: 0x7fef53708b80>
將obj2聲明改為__weak
? ? __strong NSObject *obj1=[[NSObject alloc] init];
? ? __weak NSObject *obj2=obj1;
? ? NSLog(@"%@,%@",obj1,obj2);
? ? obj1=nil;
? ? NSLog(@"%@,%@",obj1,obj2);
? ? //輸出 :
? ? //<NSObject: 0x7fef53708b80>,<NSObject: 0x7fef53708b80>
? ? //(null),(null)
從上面可以看出使用__strong 和__weak的區(qū)別碗旅,因為strong的對象會使retainCount+1,而weak的并不會悴灵。
所以第一個例子的retainCount為2扛芽,obj1=nil之后retainCount為1,并不會對obj2造成影響积瞒,而第二個例子obj1=nil之后retainCount 為0了川尖,內(nèi)存也跟著釋放了,所以obj2也為nil茫孔。
(這里提下weak和MRC時代的assign的區(qū)別叮喳,兩者都可以用于弱引用,但是內(nèi)存釋放后使用weak會將對象置nil缰贝,而assign不會馍悟,會造成野指針,現(xiàn)在assign一般只用在基礎(chǔ)類型)剩晴。
4.應(yīng)用
至于什么時候用strong 和weak锣咒?
平時一般都是用strong,也就是默認不添加赞弥,在會照成循環(huán)引用時才使用weak毅整。
當兩個不同的對象各有一個強引用指向?qū)Ψ綍r就造成循環(huán)引用,會導致對象無法釋放绽左,例如我們常用的delegate,見圖:
這就是我們在申明delegate時都是用weak的原因(MRC的話是用assign)
@property (nonatomic, weak) id<Delegate>delegate
block的使用也會照成循環(huán)引用悼嫉,比如當一個對象持有block,而該block又持有該對象時拼窥,類似下面的偽代碼會照成循環(huán)引用:
[self block:^{
? ? self.value=1;
}];
應(yīng)該改為
__weak typeof(self) weakself=self;
[self block:^{
? ? weakself.value=1;
}];
但并不是block里都需要用weak戏蔑,例如下面的代碼并不會照成循環(huán)引用:
[UIView animateWithDuration:0.2 animations:^{
? ? self.value=1;
}];
注意:只有該對象持有block,而block里的代碼塊又持有該對象時才需要用到weak鲁纠。
NSTimer也會照成循環(huán)引用总棵,所以使用了NSTimer后,釋放資源前要先調(diào)用invalidate方法
[Timer invalidate];
Timer = nil;