ios block循環參考問題

來源:互聯網
上載者:User

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方法了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.