Список захвата в закрытии: почему "слабый"?

Я прочитал эту статью о реализации MVVM, Это демонстрирует приложение master-detail, где есть первый viewController обрабатывая представление таблицы и который также содержит viewModel, такие viewModel звонки в службу поддельной службы, чтобы некоторые изображения отображались в виде таблицы. viewController а также viewModel связаны посредством замыканий.

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 который держит закрытие, которое захватывает self (viewVControllerвнутри своего тела. Это верно? Тогда почему 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],

Код доступен для скачивания из статьи, которую я упоминал, или непосредственно из этого репозитория.

0 ответов

Другие вопросы по тегам