dealloc不呼叫造成記憶體洩漏

weixin_33860722發表於2017-07-21

前言

  • 呼叫時機
  • 蘋果官方文件
    A class may provide a method definition for an instance method named
    dealloc. This method will be called after the final release of the
    object but before it is deallocated or any of its instance variables
    are destroyed.
    The superclass’s implementation of dealloc will be called automatically
    when the method returns.
    翻譯:
    dealloc方法在最後一次release後被呼叫,但此時例項變數(Ivars)並未釋放,父類的dealloc的方法將在子類dealloc方法返回後自動呼叫,也就是說物件被銷燬後會呼叫dealloc方法

使用場景

  • 重寫這個方法可以處理除了物件的例項變數之外的其他資源

  • 釋放定時器

  • 移除通知

  • 移除代理 備註:***ARC下不能呼叫父類的dealloc方法 ***

     - (void)dealloc {
        [self.timer invalidate]
        [[NSNotificationCenter defaultCenter]removeObserver:self];
     }
    

原因彙總

  • block的迴圈引用問題(90%的比例)

    • block裡面使用了self.name或者_name
      self.table.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
      self.name = @"強引用屬性";
      }];
      //解決方案
      __weak typeof(self) weakSelf = self;
      self.table.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
      weakSelf.name = @"強引用屬性";
      }];

    • block裡強引用了全域性變數
      @implementation SomeViewControllefr
      {
      NSInteger page;
      }
      self.table.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
      page+=1;//這裡模仿分頁載入場景
      }];

      // 解決 把全域性變數宣告成屬性
      @property (nonatomic,assign) NSInteger currentPage;
      
  • 強引用代理

    @property (nonatomic, strong) id<SomeDelegate> delegate;
    
  • NSTimer

      self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(someMethod) userInfo:nil repeats:YES]; 
      [self.timer setFireDate:[NSDate dateNow]];
    
      //解決
       if (self.timer && [self.timer isValid]) {
          [self.timer invalidate];
          self.timer = nil; // 不置為nil也行 
        };
    

後續

相關文章