iOS Swift 关于内存管理需要注意的地方

2019-04-30  本文已影响0人  有虫吃

1.为避免循环引用,在使用代理时声明为weak对象

weak var delegate:  MyDelegate

2.使用closure闭包时注意不要形成循环引用

lazy var someClosure: (Int, String) -> String = {
    [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
    // closure body goes here
}

3.push出来的子控制器,导航栏控制器会对该子控制器进行强引用,其中 push 对应着 pop 则控制器会被销毁。其push的本质是入栈,所有的子控制器放在数组中,先进后出,如果导航栏作为根控制器。此时需要更该根控制器,不管push了多少子控制器入栈了。其最后只需要在当前显示的子控制器中对根控制器重新赋值即可。即原先的导航栏控制器没有对象强引用它,它会被释放,其所有的子控制器自然都会被释放了(前提是你本身代码不存在其他内存泄漏)

     UIApplication.shared.keyWindow?.rootViewController = newRootVC

注意:只要有present出来的控制器,一定要有对应的dismiss,否则项目中会存在无法估量的bug。
ViewController push ---->firstVC1 present--->firstVC2 。则如何在firstVC2中切换根控制器,并同时销毁之前的控制器。则必须先dismiss掉 firstVC2 。

dismiss(animated: false) {

UIApplication.shared.keyWindow?.rootViewController = newRootVC

}

判断当前Controller 是否是被present出来的可以用一下方法判断

 if self.presentingViewController != nil {
       self.dismiss(animated: false, completion: {
             UIApplication.shared.keyWindow?.rootViewController = tabBarController
          })
  }

4.Timer计时器使用时会默认形成强引用,在Timer有效的时候,引用Timer对象的对象不会执行deinit方法,所以不能再deinit里边设置self.timer?.invalidate(),self.timer = nil,要在确定需要释放这个对象的时刻调用先把Timer释放掉。

上一篇下一篇

猜你喜欢

热点阅读