为什么Swift中的闭包默认是非逃逸闭包?
Swift 闭包默认采用非逃逸设计的核心考量
Swift 从3.0版本开始将闭包的默认行为从逃逸修改为非逃逸,核心考量主要集中在内存安全、性能优化、语义明确三个维度:
- 内存安全优化,降低引用循环风险
非逃逸闭包的生命周期严格绑定在当前函数的执行周期内,函数返回前一定会被执行完成并销毁,不会被函数外部的变量持有存储。这种特性下闭包即使捕获了self也不会产生循环引用,开发者不需要额外编写weak/unowned修饰符处理引用关系,大幅降低了内存泄漏的概率。
示例代码:
// 此处的transform闭包默认是非逃逸类型 func customMap<T>(_ array: [Int], transform: (Int) -> T) -> [T] { var result = [T]() for num in array { result.append(transform(num)) } return result } // 调用时捕获self不需要额外处理内存风险 let mappedArray = customMap([1,2,3]) { $0 * self.multiplier }
编译期性能优化空间
编译器可以明确感知非逃逸闭包的生命周期边界,不需要为其分配堆内存,直接在栈上分配内存即可,同时可以省略大量不必要的ARC引用计数操作(retain/release调用),运行时执行效率远高于逃逸闭包。高频调用的非逃逸闭包相比逃逸闭包性能提升可达数倍。代码语义显性化,降低心智负担
默认非逃逸的规则下,开发者只要看到闭包参数被显式标记了@escaping,就可以立刻判断该闭包会被存储到函数外部、晚于函数返回时间执行,比如异步网络请求回调、GCD延时执行任务等场景。风险点被显性标记后,开发者不需要逐函数排查闭包的生命周期,编写和维护代码的成本大幅降低。
内容的提问来源于stack exchange,提问作者Rohit Kumar
相关产品推荐
相关产品推荐

