你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> ios block循環引用問題

ios block循環引用問題

編輯:IOS開發綜合

ios開發中,開了ARC模式,系統自動管理內存,如果程序中用到了block就要注意循環引用帶來的內存洩露問題了

這幾天遇到一個問題,正常頁面dismiss的時候是要調用dealloc方法的,但是我的程序就是不調用,研究了好久終於找到了問題出在哪裡了

起初的代碼如下:


- (void)getMyrelatedShops

{

    [self.loadTimer invalidate];

    self.loadTimer = [NSTimer scheduledTimerWithTimeInterval:0.1

                                                 target:discoverView

                                               selector:@selector(loadWaiting)

                                               userInfo:nil

                                                repeats:YES];

    

    sendedRequest = [[FindShopService sharedInstance] getMyRelatedShopsWithPageNO:pageNo

                                                                     successBlock:^(TMRequest *request){

                                                                         [self.loadTimer invalidate];

                                                                         [self shopListRequestFinished:request];

                                                                     }failedBlock:^(TMRequest *failedRequest){

                                                                         [self.loadTimer invalidate];

                                                                         [self shopListRequestFailed:failedRequest];

                                                                     }];

}

代碼表面上看起來沒有什麼問題,但是細細研究就會發現兩個問題

1、block中引用到self,self 被block retain,sendedRequest又retain了該block的一根拷貝

2.sendedRequest是在self類中定義賦值,因此是被self retain

因此就形成了循環引用,不會調用dealloc

還有一個問題,只要重復性 timer 還沒有被 invalidated,target 對象就會被一直持有而不會被釋放。因此當你使用 self 當作 target 時,你就不能期望在 dealloc 中 invalidate timer,因為在 timer 沒有被invalidate 之前,dealloc 絕不會被調用。因此,需要找個合適的時機和地方來 invalidate timer,但絕不是在 dealloc 中。

修改如下


- (void)getMyrelatedShops

{

    [self.loadTimer invalidate];

    self.loadTimer = [NSTimer scheduledTimerWithTimeInterval:0.1

                                                 target:discoverView

                                               selector:@selector(loadWaiting)

                                               userInfo:nil

                                                repeats:YES];

   

    __unsafe_unretained FindShopVC *wfindShopVC = self;

   

    sendedRequest = [[FindShopService sharedInstance] getMyRelatedShopsWithPageNO:pageNo

                                                                     successBlock:^(TMRequest *request){

                                                                         [wfindShopVC.loadTimer invalidate];

                                                                         [wfindShopVC shopListRequestFinished:request];

                                                                     }failedBlock:^(TMRequest *failedRequest){

                                                                         [wfindShopVC.loadTimer invalidate];

                                                                         [wfindShopVC shopListRequestFailed:failedRequest];

                                                                     }];

}

這樣就避免了循環引用,頁面注銷時就會調用dealloc方法了

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved