在我的代码中,我已经实现了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,并且不允许在执行该块之前将其取消初始化。

09-11 13:27