我经历了Swift Closures和ARC in Swift,我感到很困惑。
我有简单的方法来调用Web服务和使用响应数据 这是我的基本实现:
class WebServices: NSObject {
func requestDataFromServer(completion: @escaping (_ data: Data?) -> Void) {
//web service call here
completion(Data())
}
deinit {
print("WebServices deinitializer...")
}
}
class Controller: NSObject {
private let webService = WebServices()
private func useResponseData(_ data: Data) {
print("Response Data: \(data)")
}
func fetchData() {
webService.requestDataFromServer { (data) in
if let responseData = data {
self.useResponseData(responseData)//direct use of self
}
}
}
deinit {
print("Controller deinitializer...")
}
}
var controller: Controller? = Controller()
controller!.fetchData()
controller = nil
控制台输出为:
响应数据:0字节
控制器取消初始化...
Web服务取消初始化......
我的问题是,即使我在封闭内直接使用self
,为什么此实施不会导致参考保留周期?
如果我使用unowned
或weak
,那么也会使用相同的行为。
在上述情况下,什么可能导致引用保留周期?(我不想引起,而是想要意识到错误)
答案 0 :(得分:2)
您的代码中没有问题,因为requestDataFromServer
直接调用完成处理程序(无异步)。因此,呼叫期间呼叫者无法释放。
但是当你实现webservice的真实呼叫时,它将是异步的。因此,用户可以在Web服务回答之前切换页面。在这种情况下,您将保留对控制器的强引用,并且它永远不会被释放。你应该在你的闭包中使用[weak self]
(所以调用self?.useResponseData(responseData)
并将self作为可选项。)
unowned
答案 1 :(得分:0)
好吧,我猜问题就是你在这里做的事实上并不是异步,所以它会一个接一个地执行,这段代码导致内存泄漏:
<div [ngSwitch]="social">
<div [style.display]="social == 'activity' ? 'block' : 'none'">
<div #map id="map"></div>
</div>
<div *ngSwitchCase="'messages'">
Some text.....
</div>
</div>