Swift 的逃逸闭包和非逃逸闭包

Aug 30, 2020 • 预计阅读时间 1 分钟

Swift 里的闭包(Closure)对应 ObjC 里的代码块(Block)。

众所周知,在闭包里引用外部变量其引用数会递增,但如果是在闭包所在的方法内部立即就执行的,引用数递增是没有必要的。

为了让编译器能优化这种情况,Swift 为此增加了两个注解:@escaping@noescape

@escaping:逃逸性闭包,表示告诉编译器这个闭包是稍后才执行的,里面的变量需要被捕获。

@noescape:非逃逸闭包,闭包现在就会被执行,告诉编译器不要捕获里面的变量。

Swift 里对不加注明的闭包,都会当作非逃逸闭包@noescape)处理。

但是对于可选类型的闭包,比如:((Int)->())?,默认是逃逸闭包@escaping)。

默认情况下 Swfit 会把 ObjC 的代码块(Block)都当成逃逸闭包处理,为了能和 Swift 更好的兼容,ObjC 提供了一个宏:NS_NOESCAPE

NS_NOESCAPE 对应 Swift 里的 @noescape,需要在非逃逸的代码块的声明和实现里都标明上这个宏:

- (void)foo:(NS_NOESCAPE void (^)(void))block;

- (void)foo:(NS_NOESCAPE void (^)(void))block {
    // ...
}
Swift
版权声明:如果转发请带上本文链接和注明来源。

lvv.me

iOS/macOS Developer

创建 Visual Studio C++ 离线安装包

*** -[UIKeyboardLayoutStar release]: message sent to deallocated instance