在我的代码中,我已经实现了APIManager
ArticleAPIManager
及其子类deinit { print("deinit className") }
我试图查看以下代码是否会立即解除分配:
ArticleManager().fetchArticlesWithParameters(ArticlesParameters.defaultParameters()) { (articlesData, error) -> Void in
print("Done")
}
控制台显示以下内容:
deinit ArticleAPIManager
deinit APIManager
Done
如果之前已取消分配管理器,完成处理程序如何仍然存在?
func fetchArticleWithParameters<R:xxxProtocol>(parameters:R , completionHandler: ArticleCompletionHandler) {
if let articleURLWithParamsURL = params.endPointURL() {
fetchURL(articleURLWithParameters) { (jsonData, error) -> Void in
guard let jsonData = jsonData else {
completionHandler(articlesData: nil, error: error)
return
}
if let rawArray = jsonData["data"] as? [APIJSON] {
let articles = APIGenericResponceParser<T>().parseArray(rawArray)
completionHandler(articlesData: articles, error:nil)
}
}//fetchURL
}//iflet-NSURL
}
答案 0 :(得分:1)
试图通过一个简单的例子来解释:
class Test {
let someProperty = "Very nice property"
func printWithDelay() {
//Prints done after 3 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC * 3)), dispatch_get_main_queue()) {
print("Done")
}
}
deinit {
print("\(self) is deinited")
}
}
并使用此代码:
var test: Test? = Test()
test?.printWithDelay()
test = nil
在此示例中,dispatch_after
的块不引用任何 Test
的属性,所以它不保留,这就是为什么你会看到
Test is deinited
Done
在控制台中,就像在你的例子中一样。但是,如果您在someProperty
中打印printWithDelay
,例如:
func printWithDelay() {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC * 3)), dispatch_get_main_queue()) {
print(self.someProperty)
}
}
然后你会看到
Very nice property
Test is deinited
在控制台中,因为dispatch_after
的块保留self
并且在块执行之前不会让它被删除。
答案 1 :(得分:0)
闭包是Swift中的引用类型。您可以像其他任何“常用”对象一样将它们从一个地方传递到另一个地方。
每当你为一个常量或一个变量赋一个函数或一个闭包时,你实际上是将该常量或变量设置为函数或闭包的引用 ...这也意味着如果你为两个不同的常量或变量分配一个闭包,这些常量或变量都将引用相同的闭包:
在您的情况下,您可以completionHandler
并将其传递给fetchURL
(通过endPointURL
),然后由fetchURL
捕获并保持活跃,即使{的对象为{通过它的{1}}已经死了。完成提取后,将执行完成处理程序。在您的情况下,它在ArticleAPIManager
的对象被取消初始化之后就已经发生了。