闭包捕获列表:为什么“弱”?

时间:2018-07-02 06:24:09

标签: ios closures weak-references retain-cycle unowned-references

我阅读了article的有关实现MVVM的内容。它展示了一个主从应用程序,其中第一个viewController处理表格视图,并且还包含一个viewModel。这样的viewModel调用了模拟服务,以使某些图片显示在表视图中。 viewControllerviewModel通过闭包进行绑定。

viewController像这样:

lazy var viewModel: PhotoListViewModel = {
    return PhotoListViewModel()
}()

func initVM() {

    // Some code here

    viewModel.reloadTableViewClosure = { [weak self] () in
        DispatchQueue.main.async {
            self?.tableView.reloadData()
        }
    }

    viewModel.initFetch()

}

还有viewModel

private var cellViewModels: [PhotoListCellViewModel] = [PhotoListCellViewModel]() {
    didSet {
        self.reloadTableViewClosure?()
    }
}

var reloadTableViewClosure: (()->())?

init( apiService: APIServiceProtocol = APIService()) {
    self.apiService = apiService
}

func initFetch() {
    self.isLoading = true
    apiService.fetchPopularPhoto { [weak self] (success, photos, error) in
        self?.isLoading = false
        if let error = error {
            self?.alertMessage = error.rawValue
        } else {
            self?.processFetchedPhoto(photos: photos)
        }
    }
}

private func processFetchedPhoto( photos: [Photo] ) {
    self.photos = photos // Cache
    var vms = [PhotoListCellViewModel]()
    for photo in photos {
        vms.append( createCellViewModel(photo: photo) )
    }
    self.cellViewModels = vms
}

我需要了解此代码示例中的捕获列表:

1。。看到viewController

看来您实际上可以在那里拥有一个强大的参考周期,对吗? viewController包含对viewModel的引用,该引用包含一个闭包,该闭包将selfviewVController)捕获在其主体内。那是对的吗?那么,为什么reloadTableViewClosure[weak self]方法设置initVM()

这个viewModel应该是根源,因此它在整个应用程序生命中都还活着,所以实际上viewModel的寿命可能较短,对吧?那不意味着应该使用unowned来代替?

要考虑的另一件事是,也许viewModel可以调用另一个对象来执行异步任务,然后viewModel将被此类对象保留,直到异步任务返回,对吗?然后,这种情况可能会更改我之前提到的viewController中的捕获列表?

1。。看到viewModel

在其initFetch()方法中,将调用apiService对象。在这种情况下,它看起来要执行同步任务,但是如果它是真正的REST服务调用,它将是异步的。无论如何,apiService对象将保留viewModel,直到其任务完成,对吗?因此,同样,那里可能会有一个强大的参考保留周期->传递给apiService的闭包为@escaping,并且self被捕获在主体中。正确吗?

此处捕获列表也为[weak self]。当weak的寿命可以缩短时,您设置self吧?但是viewModel的生命是否可以短于apiService回调的生命? apiService是否保留viewModel。另一方面,由于viewModel是由根viewController持有的,因此整个应用程序生命也不会一整天吗?

我需要澄清一些信息,以了解那里潜在的强参考周期以及为什么所有这些捕获列表都考虑使用[weak self]

可以从article I mentioned或直接从repo

下载代码。

0 个答案:

没有答案