iOS 內(nèi)存泄漏之循環(huán)引用

何為循環(huán)引用?
簡(jiǎn)單理解:對(duì)象A強(qiáng)引用B,對(duì)象B也強(qiáng)引用A;

何時(shí)會(huì)發(fā)生循環(huán)引用?
使用delegate、block的時(shí)候

Example:
新建一個(gè)Friend類如下:

#import <Foundation/Foundation.h>

typedef void(^FriendBLK)(NSString *name);

@interface Friend : NSObject
@property (nonatomic, strong) NSArray *arr;
@property (nonatomic, copy) FriendBLK block;

@end
#import"Friend.h"
@implementationFriend
- (id)init
{
if(self= [superinit]) {
self.arr=@[@111,@222,@333];
self.block= ^(NSString*name){
NSLog(@"name :%@ , block arr:%@", name, name);
};
}
returnself;
}
- (void)dealloc{
NSLog(@"Friend dealloc");
}
@end

然后使用的地方調(diào)用下:

Friend*f = [[Friendalloc]init];
f.block(@"yk-test");

當(dāng)f所在的runloop結(jié)束時(shí),會(huì)發(fā)現(xiàn)控制臺(tái)打印
2016-09-07 10:20:15.264 RACDemo[2459:23583] name :yk-test , block arr:yk-test
2016-09-07 10:20:15.264 RACDemo[2459:23583] Friend dealloc
這表明f對(duì)象被釋放了,不存在內(nèi)存泄漏。然后我們稍微修改下代碼:

?再次運(yùn)行下,發(fā)現(xiàn)只會(huì)打印
2016-09-07 10:27:24.216 RACDemo[2510:28277] name :yk-test , block arr:(
111,
222,
333
)
并不會(huì)調(diào)用dellaoc釋放self 也就是f對(duì)象未被釋放,即存在內(nèi)存泄漏;為了更好理解引用循環(huán)問題,我們添加一個(gè)延遲隊(duì)列,代碼如下:

然后發(fā)現(xiàn)f對(duì)象也是不釋放的,下面來分析原理:

外面f.block(@"yk-test");結(jié)束后,需要釋放f對(duì)象,通知即將釋放,但是這時(shí)候block內(nèi)部還在強(qiáng)引用自己的arr?數(shù)組。?Runloop發(fā)現(xiàn)f的retain count不為0,于是乎f就不能釋放。等到block里面的引用self釋放之后,也就是retain count為0時(shí),才能正在釋放;

解決方案:弱引用
__weak__typeof(self)wself =self; 或者使用@weakify() @strongify()

原理示意圖:


基本Block的問題解決了。其實(shí)我們?cè)谑褂胐elegate的時(shí)候也會(huì)出現(xiàn)同樣的問題,所以使用delegate都用weak,而不能用strong;


以上就是日常開發(fā)的內(nèi)存泄漏之循環(huán)引用了,有不對(duì)的地方請(qǐng)留言;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容