При копировании структуры с weak-свойством сколько независимых слабых ссылок получает копия?
Копия получает собственное хранилище weak-ссылки, но оно указывает на тот же экземпляр. Копирование структуры не создаёт сильного владения объектом: если исчезнет последняя сильная ссылка, ARC уничтожит объект и автоматически обнулит обе слабые ссылки.
ARC был создан, чтобы управлять временем жизни экземпляров классов автоматически, без ручных операций retain и release. При этом Swift сохраняет различие между значениями, которые копируются независимо, и ссылочными объектами, идентичность которых при копировании сохраняется.
Слабые ссылки нужны для представления невладеющих связей. Это позволяет хранить ссылку на объект внутри копируемой структуры, не продлевая время жизни объекта и не создавая retain cycle.
Структура копируется по значению, поэтому важно отличать копирование самой структуры от копирования объекта, на который она ссылается. Ошибочное ожидание, что копия станет сильным владельцем объекта, может привести к преждевременному уничтожению объекта или к неверному анализу графа владения.
При уничтожении объекта все связанные с ним weak-ячейки должны быть обнулены. Поэтому копии структуры должны вести себя независимо при присваивании своих слабых свойств, но одинаково реагировать на уничтожение общего объекта.
При копировании структуры Swift копирует значение её weak-свойства как слабую ссылку. Копия не получает сильную ссылку на объект и не увеличивает его устойчивое число сильных владельцев.
У каждой копии есть отдельная weak-ячейка. Если в одной структуре присвоить свойству nil, это изменит только эту ячейку. Если же объект будет уничтожен из-за исчезновения последней сильной ссылки, ARC обнулит все weak-ячейки, указывающие на него.
Чтение weak-ссылки временно получает сильное удержание на время конкретного обращения. Однако само хранение ссылки в структуре объект живым не сохраняет.
После присваивания owner = nil других сильных владельцев нет, поэтому Item становится доступен для уничтожения. Обе копии WeakBox содержат слабые ссылки на один объект, и ARC обнуляет обе.
Это отличается от структуры с обычным сильным свойством: копирование такой структуры сохраняет объект живым, потому что каждая копия владеет им сильной ссылкой.
Допустим, очередь задач хранит набор копируемых дескрипторов экранов, но не должна удерживать сами экраны после их закрытия. В дескрипторе можно использовать сильную ссылку, слабую ссылку или идентификатор объекта.
Сильная ссылка проста, но продлевает жизнь экранов и может вызвать утечку при ошибочном графе владения. Один общий слабый контейнер снижает риск удержания, но требует учитывать, что объект может исчезнуть в любой момент. Идентификатор не создаёт ссылочной связи, однако для получения объекта понадобится отдельный реестр и дополнительная логика синхронизации.
Подход со структурой, содержащей weak-свойство, подходит, если дескрипторы должны копироваться по значению, а отсутствие объекта должно корректно обрабатываться. При передаче дескриптора между потоками одной ARC недостаточно: доступ к изменяемым переменным и контейнерам всё равно должен быть синхронизирован.
Изменение weak-свойства в одной копии обнулит его в другой?
Нет. При копировании структуры создаются независимые weak-ячейки. Присваивание nil одной ячейке не меняет другую. Обе ячейки станут nil только при уничтожении объекта, на который они указывают, либо если каждая из них будет изменена отдельно.
Может ли передача такой структуры по значению сохранить объект живым на время вызова?
Сама передача не создаёт долговременного сильного владения. Если внутри функции прочитать weak-свойство в локальную сильную переменную, объект будет временно удерживаться этой переменной до окончания её времени жизни. Без такого чтения структура остаётся лишь невладеющим контейнером.
Что произойдёт, если объект уничтожается одновременно с чтением weak-ссылки?
Корректное чтение weak-ссылки даёт либо nil, либо временно сильную ссылку на живой объект; это предотвращает уничтожение объекта посреди конкретного обращения. Но ARC не делает потокобезопасными саму структуру, присваивания её свойствам или внешний граф данных. Для согласованного доступа из нескольких потоков нужны синхронизация или изоляция средствами concurrency.