第一次掉進block循環(huán)引用的坑

背景

最近碰到一個需求,做視頻播放的時候要求監(jiān)控網(wǎng)絡狀態(tài),若網(wǎng)絡狀態(tài)改變,比如沒網(wǎng)到有網(wǎng),自動刷新視頻詳情文案。

于是我就在視頻播放VC里面的viewDidLoad方法里面加入了這一段代碼


- (void)monitorNetWorkStart

{

// 1.獲得網(wǎng)絡監(jiān)控的管理者

AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];

// 2.設置網(wǎng)絡狀態(tài)改變后的處理

[mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

// 當網(wǎng)絡狀態(tài)改變了, 就會調(diào)用這個block

switch(status) {

case AFNetworkReachabilityStatusUnknown:// 未知網(wǎng)絡

break;

case AFNetworkReachabilityStatusNotReachable:// 沒有網(wǎng)絡(斷網(wǎng))

break;

case AFNetworkReachabilityStatusReachableViaWWAN:// 手機自帶網(wǎng)絡

[self loadVideoDeatailDefault];  // 請求數(shù)據(jù)刷新界面

break;

case AFNetworkReachabilityStatusReachableViaWiFi:// WIFI

[self loadVideoDeatailDefault];

break;

}

}];

// 3.開始監(jiān)控

[mgr startMonitoring];

}

本以為問題解決了,然而又出現(xiàn)了新的問題,退出視頻頁的時候,視頻還在繼續(xù)播放!!!

這妥妥的VC沒釋放啊,因為之前從沒實戰(zhàn)過,所以查了一些資料找到了問題所在

坑是怎么出現(xiàn)的

AFNetworkReachabilityManager是一個單例,它持有了一個block屬性,單例在進程死掉之前不會被釋放,所以block的引用計數(shù)一直為1。

在block中調(diào)用了 視頻播放VC 的方法,所以block持有了 視頻播放VC ,視頻播放VC引用計數(shù)+1,并且因為block不會被釋放,所以 視頻播放VC 也不會被釋放。

在block中調(diào)用某個對象的方法,或者用了某個對象的屬性,block就會持有該對象,而不是該對象的方法或?qū)傩?/p>

怎么解決


- (void)monitorNetWorkStart

{

// 1.獲得網(wǎng)絡監(jiān)控的管理者

AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];

// 2.設置網(wǎng)絡狀態(tài)改變后的處理

__weak __typeof__(self) weakSelf = self;

[mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {

__typeof__(self) self = weakSelf;

if (self.navigationController.topViewController != self) {

return;

}

// 當網(wǎng)絡狀態(tài)改變了, 就會調(diào)用這個block

switch(status) {

case AFNetworkReachabilityStatusUnknown:// 未知網(wǎng)絡

break;

case AFNetworkReachabilityStatusNotReachable:// 沒有網(wǎng)絡(斷網(wǎng))

break;

case AFNetworkReachabilityStatusReachableViaWWAN:// 手機自帶網(wǎng)絡

[self loadVideoDeatailDefault];  // 請求數(shù)據(jù)刷新界面

break;

case AFNetworkReachabilityStatusReachableViaWiFi:// WIFI

[self loadVideoDeatailDefault];

break;

}

}];

// 3.開始監(jiān)控

[mgr startMonitoring];

}

  • 加__weak __修飾self可以使block不持有 視頻播放VC,VC該釋放的時候就釋放

  • typeof(self) self = weakSelf; 這句可以防止 在執(zhí)行block時self被釋放造成crash

后記

小白一枚,如果哪里說的不對,請指正~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容