我有一个像这样的视图控制器:
class PublicationListViewController: UIViewController {
var publicationQuery: (() -> [Publication])!
func initWith(title: String, publicationQuery: () -> [Publication]) {
self.title = title
self.publicationQuery = publicationQuery
}
}
为什么我会收到"分配非转义参数' publicationQuery'到一个@escaping关闭"错误?
答案 0 :(得分:5)
转出闭包
因为通过将publicationQuery
存储到属性中,您可以让它“逃避”#34;来自初始化程序(它甚至在initiliazer完成执行后仍然存在,因此是保留周期的潜在原因)。为此,您必须使用@escaping
注释将其明确标记为转义:
class PublicationListViewController: UIViewController {
var publicationQuery: (() -> [String])!
// notice that now publicationQuery uses @escaping annotation
func initWith(title: String, publicationQuery: @escaping () -> [String]) {
self.title = title
self.publicationQuery = publicationQuery
}
}
详细了解Closures documentation中转义闭包部分中的转义。
防止保留周期
使用转义闭包时,必须注意不要创建保留周期。最简单的方法是在创建转义闭包时使用capture list,并在该捕获列表中明确捕获self
作为weak
引用:
// use [weak self] capture list to make sure that you don't create another strong reference to self
pubController.initWith(title: "Title") { [weak self] () -> [String] in
// use guard to safely unwrap the self
guard let `self` = self else { return }
// here self will be non-optional value that you can directly use
}