Ios 为什么@noescape不能在需要时自动应用于Swift闭包?
我想知道为什么标记Ios 为什么@noescape不能在需要时自动应用于Swift闭包?,ios,swift,closures,Ios,Swift,Closures,我想知道为什么标记noescape没有被自动检测到,需要显式应用它 事实上,它是在编译时检测到的,因为尝试将@noescape标记添加到带有转义闭包的func会导致错误 所以问题是为什么。。。为什么需要显式添加noescape,而Apple没有创建它以便在需要时自动添加?编辑:Swift 3在这里做了一些更改: 现在,如果需要非转义闭包,则不必将@noescape应用于将闭包作为参数的函数声明。(相反,如果确实计划在函数返回后存储闭包,则必须应用@escaping。) 闭包的“逃逸性”。因此,
noescape
没有被自动检测到,需要显式应用它
事实上,它是在编译时检测到的,因为尝试将@noescape标记添加到带有转义闭包的func会导致错误
所以问题是为什么。。。为什么需要显式添加noescape,而Apple没有创建它以便在需要时自动添加?编辑:Swift 3在这里做了一些更改:
- 现在,如果需要非转义闭包,则不必将
应用于将闭包作为参数的函数声明。(相反,如果确实计划在函数返回后存储闭包,则必须应用@noescape
。)@escaping
- 闭包的“逃逸性”。因此,它不是一个看起来像
,而是@escaping completionHandler:(Bool,Error)->Void
completionHandler:@escaping(Bool,Error)->Void
@noescape
不仅仅是编译器优化的提示;它是函数声明呈现给调用方的接口的一部分。无论函数的参数是声明为@noescape
还是允许转义闭包,都会改变函数调用方将闭包作为参数传递的方式
例如,给定函数(来自SequenceType
):
如果我想根据需要在self
上调用方法的某些条件筛选集合,我知道我可以安全地这样做,而不用担心闭包是否会捕获self
并创建保留周期
// horribly contrived example
class Foo {
var things: [Thing]
func isCurrentlyAwesomeThing(thing: Thing) -> Bool { /*...*/ }
func thingsThatAreAwesomeRightNow() -> [Thing] {
return things.filter {
return isCurrentlyAwesomeThing($0)
}
}
}
如果filter
允许转义闭包,则调用iscurrentlyWesomething()
的闭包将捕获self
。(因此需要使用显式的self.
前缀调用该方法。)如果filter
的实现实际上将闭包保存在该函数的运行时间之外,内存泄漏是因为闭包保留了self
,而self
保留了filter
函数接收闭包的数组
当您调用一个闭包参数未声明为@noescape
的函数时,您必须考虑这种可能性。这就是为什么您会看到这样的调用:在闭包中添加一个[weak self]
捕获列表和一个强大的重新声明,以确保self
在闭包过程中不会被释放。(或者至少是一个[unowned self]
,如果您合理地确定关闭不会持续超过self
)
如果闭包参数不能被修饰为
@noescape
(或者由于没有该修饰符而无法转义),那么在调用接受闭包的函数时,您将不知道是否必须小心该闭包捕获的内容 编辑:Swift 3在此处进行了一些更改:
- 现在,如果需要非转义闭包,则不必将
应用于将闭包作为参数的函数声明。(相反,如果确实计划在函数返回后存储闭包,则必须应用@noescape
。)@escaping
- 闭包的“逃逸性”。因此,它不是一个看起来像
,而是@escaping completionHandler:(Bool,Error)->Void
completionHandler:@escaping(Bool,Error)->Void
@noescape
不仅仅是编译器优化的提示;它是函数声明呈现给调用方的接口的一部分。无论函数的参数是声明为@noescape
还是允许转义闭包,都会改变函数调用方将闭包作为参数传递的方式
例如,给定函数(来自SequenceType
):
如果我想根据需要在self
上调用方法的某些条件筛选集合,我知道我可以安全地这样做,而不用担心闭包是否会捕获self
并创建保留周期
// horribly contrived example
class Foo {
var things: [Thing]
func isCurrentlyAwesomeThing(thing: Thing) -> Bool { /*...*/ }
func thingsThatAreAwesomeRightNow() -> [Thing] {
return things.filter {
return isCurrentlyAwesomeThing($0)
}
}
}
如果filter
允许转义闭包,则调用iscurrentlyWesomething()
的闭包将捕获self
。(因此需要使用显式的self.
前缀调用该方法。)如果filter
的实现实际上将闭包保存在该函数的运行时间之外,内存泄漏是因为闭包保留了self
,而self
保留了filter
函数接收闭包的数组
当您调用一个闭包参数未声明为@noescape
的函数时,您必须考虑这种可能性。这就是为什么您会看到这样的调用:在闭包中添加一个[weak self]
捕获列表和一个强大的重新声明,以确保self
在闭包过程中不会被释放。(或者至少是一个[unowned self]
,如果您合理地确定关闭不会持续超过self
)
如果闭包参数不能被修饰为@noescape
(或者由于没有该修饰符而无法转义),那么