Передача себя и возврат в замыкании без цикла сохранения

Я устал использовать захват [weak self] в замыканиях, поэтому я хотел бы передать self и вернуть его в замыкании следующим образом:

alertManager.askToConfirm(from: self) { vc, confirmed in
        if confirmed {
            vc.model.confirm()
        } else {
            vc.model.reject()
        }
    }

внутри AlertManager мой код будет таким:

func askToConfirm<T>(from vc: T, completion: @escaping (T) -> ()) {
    let invitation = pageItemFactory.createConfirmationPageItem() { [weak self] accepted in
        self?.dismissAlert()
        completion(vc, accepted)
    }
    present(invitation)
}

Создаст ли это цикл удержания?

В 99% случаев, если вы используете встроенное закрытие, а вызываемая функция просто хранит переданное закрытие в локальной переменной (в отличие от сохранения его в свойстве), цикла сохранения не будет, и weak self не нужен.

Paulw11 30.05.2019 13:34

@Paulw11Paulw11 когда мне может понадобиться использовать [weak vc] в блоке createConfirmationPageItem()? Я просто подумал, что может захватить vc и вызвать какой-то цикл

Tometoyou 30.05.2019 14:48

Итак, я только что попробовал это, и оказалось, что мне нужно поместить [weak vc] в блок createConfirmationPageItem(), так как он содержит сильную ссылку на него.

Tometoyou 30.05.2019 18:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
222
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, насколько я вижу, это не приведет к циклу удержания.


Например, этот буду приводит к циклу сохранения. Когда myFunction выполняется, экземпляр Foo будет содержать сильную ссылку на блок completion. В свою очередь, блок completion содержит сильную ссылку на экземпляр Foo. Это будет цикл сохранения, и в этом случае вам нужно добавить список захвата.

class Foo<T> {
  var completion: (T) -> ()

  func myFunction(_ vc: T, completion: @escaping (T) -> ()) {
    self.completion = completion // This will create a retain cycle
    completion(vc)
  }

  func doSomething() { 
    myFunction(self) { vc in
      print(vc)
    }
  }
}

Хм, я видел, как некоторые фреймворки возвращают vc без необходимости добавлять [weak self]. Как они это делают? Пример в addPlaybackStartedObserver в этой статье: swiftbysundell.com/posts/observers-in-swift-part-2

Tometoyou 30.05.2019 12:35

Это зависит от контекста. Даже если vc сохраняется, это не означает, что это приведет к циклу сохранения. Ваш пример не приведет к циклу сохранения, если только vc не содержит строгой ссылки на само закрытие. (Я обновил свой ответ, чтобы он был более ясным и правильным.)

Rengers 30.05.2019 12:37

Моя функция с закрытием фактически находится в другом классе. Self содержит сильную ссылку на этот класс, из которого он вызывается.

Tometoyou 30.05.2019 12:44

Я добавил пример. Можете ли вы опубликовать свой полный код? Это облегчит оценку того, создан ли цикл.

Rengers 30.05.2019 12:47

Нет, насколько я вижу, это не приведет к циклу удержания.

Rengers 30.05.2019 12:57

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