在我的代码中,我已经实现了APIManager
的两个类中都有一个ArticleAPIManager
和它的一个子类deinit { print("deinit className") }
。
我试图查看以下代码是否将立即释放:
ArticleManager().fetchArticlesWithParameters(ArticlesParameters.defaultParameters()) { (articlesData, error) -> Void in
print("Done")
}
控制台显示以下内容:
deinit ArticleAPIManager
deinit APIManager
Done
如果之前已取消分配Manager,则完成处理程序如何仍然存在?
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
}
最佳答案
试图通过一个简单的例子来解释:
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
,并且不允许在执行该块之前将其取消初始化。