Комментарии
1. Чтобы избежать retain circle нужно писать weak var receiverOfOrderViaElevator, а protocol InterchangeViaElevatorProtocol: AnyObject {...}
2. Не пишите [weak self] in self!..., иначе self «протухнет» и приложение упадет при force unwrapping, пишите [weak self] in self?..., или через guard: guard let self = self else {return}
Благодарю за комментарий.
Я намеренно сделал несколько допущений, чтобы не усложнять. Конечно же, я надеюсь никто из изучающих Swift не будет делать force unwrapping в своих приложениях. Я полагаю, что те, кто дошел до изучения UIKit, уже знает и про опционалы, и опасность force unwrapping, и про то, что нужно делать код безопасным через optional binding (if let или guard let). Сомневаюсь, что кто-то начинает изучение Swift сразу с делегатов, не изучив опционалы и опциональные цепочки )) Поэтому эта статья будет полезна тем, кто уже столкнулся с делегатами и колбэками и теперь лишь пытается разобраться до конца и уложить кусочки пазла в целостную картину ))
Всё верно, но бывают «залётные» ребята найдут статью, скопируют… И пока до них дойдет, кто-то уже может увидеть. Советую делать небольшой Note по этому поводу, аля «это сделано для упрощения примера, так делать не стоит, force unwrapping — зло etc»
Потрудился на славу, хорошая практика, продолжай ))
В схеме с делегатом забыл
weak var delegate
объявить. Создал retain cycle.
Метод, который что-то возвращает, называется «фабричным». Возвращать булево значение бессмысленно, если это не метод делегата, в котором за тебя уже все определили и тебе только надо сказать «да» или «нет» и объяснить в двух строчках, почему.
Используй
(completion: (Bool) -> Void)
в качестве параметра в таких случаях.
Успехов!
Безусловно вы правы во всем, спасибо. Но обо всех тонкостях в одной статье не написать, да и не это было целью. Для меня главное, чтобы читатели, такие как я, у которых до конца не складывался пазл про делегаты и колбэки, наконец-то поняли «на пальцах», как это работает и когда это применяется ))
Возвращение Bool было не обязательным, конечно. Это так, для примера. Может, стоит предупредить о этом… Надо подумать. Просто не хотел бы превращать статью еще и в разбор правил построения замыканий. Она и так очень уж большая получилась, на мой взгляд ))
Я дошел до момента
extension Waiter {
var receiverOfOrderViaElevator: InterchangeViaElevatorProtocol? { return cook }
}
Тупо вклеил код по порядку
Добрый день.
Использовать extention'ы удобно для тех, кто имеет опыт их использования. Это был пример скорее для них, нежели для всех.

Вам же рекомендую пропустить и не вставлять extension Waiter и extension Cook, как вы делали по порядку. Просто подправьте код, написанный ранее, добавив туда соответствующие строчки. Как раз далее я написал о том, что для для простоты мы удалим extention'ы (экстеншены) и перенесем строчки в код. И чуть ниже идут переделанные классы Waiter и Cook уже со всеми исправлениями и доработками. Надеюсь, что это помогло :)
Спасибо за статью!
Мне кажется немного странным порядок действий:
  1. // Добавим официанту заказ:
    waiter.takeOrder(«Chiken»)
  2. // Теперь скажем официанту, что его «получатель заказа через лифт» — это наш повар:
    waiter.receiverOfOrderViaElevator = cook
  3. // Теперь официант может нашего «получателя заказа через лифт» попросить приготовить заказ:
    waiter.receiverOfOrderViaElevator?.cookOrder(order: waiter.order!)


В самом начале статьи объявлен метод sendOrderToCook(), который вызывается в методе takeOrder(). Соответственно, я думаю, что лучше поменять порядок действий:
  1. Сказать, что в sendOrderToCook вызывается receiverOfOrderViaElevator?.cookOrder(order: waiter.order!)
  2. Назначить делегата waiter.receiverOfOrderViaElevator = cook
  3. и только после этого делать waiter.takeOrder(«Chiken»)
Да, так тоже можно. Главное, чтобы была понятна суть, как и для чего используется делегат.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.