内存泄漏(Memory Leak)是指程序中己动态分配的堆内存因为某种缘由程序未释放或没法释放,形成系统内存的浪费,致使程序运行速度减慢甚至系统崩溃等严重后果。 -- 百度百科markdown
1. 使用的 Timer ,而且 Timer 的 target 为 self
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTimer(_ :)), userInfo: nil, repeats: true)
解决方式: 在须要释放 self 时调用 Timer 的 invalidate
2. 两对象的互相强引用 (通常出如今delegate,因此 delegate 要用 weak 修饰)
class A {
var b: B
}
class B {
var a: A
}
let a = A()
let b = B()
a.b = b
b.a = a
二者互相强引用谁都释放不掉
解决方式: a 或 b 其中一个用 weak 修饰
weak var a: A
3. 闭包内部的强引用 (循环引用)
class A {
var avtion: (()->())?
}
class B{
var a: A = A()
func xx(){
a.action = {
self.xxx//(使用 self 作了一些操做)
}
}
}
解决方式:
使用[weak self] 或者 [unowned self] 来避免循环引用
a.action = { [weak self] in
guard let `self` = self else {return}//(黑魔法,闭包内能够继续使用 self )
}
unowned修饰相似于 OC 中的 assign,self 指向的是当前对象的地址,若是对象已经释放这个 self 不会自动置为 nil,此时必定要确保 self 没有释放,不然会有野指针的错误.
复制代码
1. 静态分析(预防针):
在 Xcode 菜单栏点击 Product 选择 Analyze (Command + Shift + B)
Xcode 会分析可能会形成泄露的语句
(Swift 的项目没有跑出来泄露的,就用 OC 的项目看吧)
复制代码
2. 内存泄露分析工具Leaks
Product => Profile(Command+I) => Leaks
点击左上角像录制同样的按钮 开始检测
复制代码
3. Debug Memory Graph
复制代码
在后台输出框的查看层级按钮旁边
若是咱们已经知道某个对象没有释放(好比 controller pop没有释放掉)能够经过这个方式查看到底是被谁强引用了.
复制代码
4. 人工检索(笑)
在知道没有释放掉的控制器中 Command + F 搜索 self,而后 检索下是否是在 block 中有你不当心使用的 没有 weak 处理的 self 吧.简单暴力傻瓜式(事了拂衣去,深藏身与名)复制代码