首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解Swift闭包捕获

理解Swift闭包捕获
EN

Stack Overflow用户
提问于 2017-06-13 08:35:11
回答 2查看 179关注 0票数 3

我已经通过了Swift关闭斯威夫特弧,我有点困惑。

我有调用web服务和使用响应数据的简单场景。

以下是我的基本实现:

代码语言:javascript
复制
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字节 控制器去初始化器。 WebServices去初始化器..。

我的问题是,我甚至在闭包中直接使用self,为什么这个实现没有导致引用保留周期

如果我使用unownedweak,那么也会有相同的行为。

在上述情况下,什么能导致引用保持循环?(我不想引起,而是要注意错误)

EN

回答 2

Stack Overflow用户

发布于 2017-06-13 09:25:11

代码中没有问题,因为requestDataFromServer直接调用完成处理程序(没有异步)。所以打电话的人不可能在你打电话的时候被释放。

但是,当您实现when服务的真正调用时,它将是异步的。这样用户就可以在can服务回答之前切换页面。在这种情况下,您将保留对控制器的强烈引用,并且它将永远不会被释放。您应该在闭包中使用[weak self](因此调用self?.useResponseData(responseData)并将self作为可选的)。

如果您确信引用不会为零(它不是可选的),则使用unowned

票数 3
EN

Stack Overflow用户

发布于 2017-06-13 09:10:56

好的,我想问题是您在这里所做的并不是真正的异步,所以它一个接一个地执行,这段代码会导致内存泄漏:

代码语言:javascript
复制
import Foundation

class WebServices {
    func requestDataFromServer(completion: @escaping (_ data: Data?) -> Void) {
        //web service call here
        print("called")
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
            print("called async")
            completion(Data())
        })
    }
    deinit {
        print("WebServices deinitializer...")
    }
}

class Controller: UIViewController {
    private let webService = WebServices()
    private func useResponseData(_ data: Data) {
        print("Response Data: \(data)")
    }
    func fetchData() {
        webService.requestDataFromServer { (data) in
            print("called")
            if let responseData = data {
                self.useResponseData(responseData)//direct use of self
            }
        }
        self.dismiss(animated: true, completion: nil)
    }
    deinit {
        print("Controller deinitializer...")
    }
}

var controller: Controller? = Controller()
controller!.fetchData()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44516257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档