При вызове функции с параметром borrowing или consuming для экземпляра класса какой вариант передаёт функции владение ссылкой, а какой лишь временно заимствует её?
Параметр borrowing временно заимствует значение: функция получает доступ к экземпляру только на время вызова и не принимает владение ссылкой. Параметр consuming передаёт функции владение аргументом, поэтому исходное значение у вызывающего кода считается потреблённым и не может использоваться как прежде без копирования или повторной инициализации.
Обычные соглашения о параметрах Swift скрывают детали владения за автоматическим управлением памятью. ARC обычно расставляет операции удержания и освобождения сам, но для производительных или низкоуровневых участков этого недостаточно: разработчику может быть важно явно выразить, передаётся ли владение или требуется только временный доступ.
borrowing и consuming относятся к модели владения Swift. Они позволяют описать намерение API и дать компилятору дополнительные гарантии для оптимизации, не превращая управление памятью в ручной вызов retain и release.
Если функция только синхронно читает объект, передача владения ей не нужна. Использование consuming в таком случае усложняет контракт: вызывающий код больше не может безусловно обращаться к исходному значению после вызова.
Обратная ошибка тоже опасна. Если функция должна сохранить ссылку, вернуть её или передать дальше как собственный ресурс, одного borrowing недостаточно: заимствование ограничено временем вызова и не может произвольно пережить его.
borrowing означает заимствование. Объект гарантированно жив во время вызова функции, но функция не становится его владельцем и не может считать ссылку своей после завершения вызова. Такой параметр не является аналогом weak: исходный владелец продолжает существовать, а объект не исчезает из-за самого факта заимствования.
consuming означает передачу владения функции. Для локального значения это обычно означает, что после передачи исходное значение считается потреблённым: его нельзя использовать как прежнее, пока оно не будет заново инициализировано или отдельно скопировано. Функция может удерживать полученное владение, передать его дальше или освободить, когда оно больше не нужно.
Для экземпляра класса передаётся не сам объект, а владение ссылкой на него. Другие сильные ссылки могут продолжать удерживать тот же экземпляр, поэтому consuming не гарантирует немедленный вызов deinit после завершения функции.
Также нельзя рассматривать эти модификаторы как прямую инструкцию «добавить retain» или «убрать release». Компилятор и ARC могут оптимизировать операции, а фактическое время уничтожения зависит от всех сильных владельцев и допустимых оптимизаций. Семантическая гарантия касается владения и допустимого использования значения, а не конкретного количества инструкций управления памятью.
Для синхронной функции, которая только читает экземпляр и не сохраняет ссылку, обычно подходит borrowing. Если функция получает право распоряжаться переданным значением или должна передать его в долгожившее хранилище, уместен consuming.
Команда оптимизирует синхронный обработчик больших объектов-моделей. Обработчик только проверяет состояние модели и не сохраняет ссылку. Если объявить параметр как consuming, вызывающий код потеряет возможность использовать исходное значение после вызова, хотя обработчику передача владения не нужна.
Вариант с обычным параметром проще, но не выражает намерение API явно и может потребовать лишних операций владения. Вариант с consuming корректен для функции, которая принимает модель в собственность и передаёт её в очередь, но избыточен для чтения.
Выбран borrowing: модель гарантированно живёт во время синхронного чтения, функция не получает право хранить ссылку после возврата, а контракт предотвращает случайное использование параметра как переданного ресурса. Это уменьшает стоимость владения там, где она действительно существенна, но не меняет логическую жизнь объекта при наличии других владельцев.
Нет. borrowing не обнуляется при уничтожении объекта и не допускает обращение к потенциально отсутствующему экземпляру. Это временное заимствование уже существующего значения с гарантией его доступности на протяжении вызова. weak — это отдельный вид хранилища, не владеющий объектом и автоматически обнуляемый при его уничтожении.
Нет. consuming передаёт функции одно владение, но у объекта могут оставаться другие сильные ссылки: свойства, коллекции, замыкания, задачи или глобальные хранилища. deinit будет возможен только после освобождения последнего сильного владельца, поэтому consuming нельзя использовать как механизм принудительного уничтожения.
Нужно заранее сохранить отдельную копию ссылки либо выбрать не потребляющий вариант параметра. Для экземпляра класса копирование значения обычно создаёт ещё одну ссылку на тот же объект, а не новый экземпляр, поэтому состояние объекта остаётся общим, но исходная переменная получает независимое владение ссылкой.