Ответ
Место хранения: Сама strong-ссылка как переменная хранится в стеке (для локальных переменных) или в куче (если является свойством класса). Объект, на который она указывает, всегда размещается в куче (heap).
Принцип работы (ARC): Strong-ссылка увеличивает счетчик ссылок (retain count) объекта. Пока существует хотя бы одна strong-ссылка, объект не освобождается.
Пример:
class Person {
let name: String
init(name: String) { self.name = name }
}
// Создание strong-ссылок
var strongRef1: Person? = Person(name: "Alice") // retain count = 1
var strongRef2 = strongRef1 // retain count = 2 (новая strong-ссылка)
strongRef1 = nil // retain count = 1
strongRef2 = nil // retain count = 0 -> объект деаллоцируется
Ключевые особенности:
- По умолчанию: Все ссылки в Swift — strong.
- Управление памятью: Автоматическое (ARC). Присваивание увеличивает счетчик, обнуление переменной — уменьшает.
- Циклические ссылки: Могут возникнуть, если два объекта имеют strong-ссылки друг на друга. Решаются через
weakилиunowned.
Ответ 18+ 🔞
А, ну это про наши любимые strong-ссылки, да? Ну слушай, история проще пареной репы, но если не врубиться — потом циклическая зависимость накроет твой проект медным тазом, и будешь рыдать, как Герасим над Муму.
Вот смотри, представь себе объект в памяти — это как квартира в новостройке. Strong-ссылка — это твой договор аренды, оформленный у нотариуса, с печатями, блядь. Пока этот договор лежит у тебя в столе (то есть переменная существует), квартира (объект) твоя, и сносить её никто не имеет права. Сделал копию договора — отдал жене? Отлично, теперь у объекта два законных владельца. Пока хоть один держит свою копию, объект живёт.
Где этот договор-ссылка валяется? Да где угодно! Если переменная локальная — в стопке, на стеке, как чек из магазина. Если это свойство какого-нибудь жирного класса — то уже в куче, в сейфе. Но, внимание, ёпта! Сама квартира, сам объект — он ВСЕГДА в куче. На стеке только бумажки с адресом.
Как работает их чёрная магия (ARC)? Очень просто, блядь. У каждой квартиры (объекта) есть счётчик жильцов. Создал strong-ссылку — заселил одного жильца, счётчик: 1. Скопировал ссылку в другую переменную — заселил второго, счётчик: 2. Обнулил одну переменную — один жилец съебал, счётчик: 1. Обнулил последнюю — квартира пуста, счётчик: 0, и тут же приезжает бульдозер памяти и сравнивает объект с землёй. Деаллокация, пиздец.
Вот, смотри на живом примере, как эти мудаки-жильцы заселяются и выселяются:
class Person {
let name: String
init(name: String) { self.name = name }
}
// Создание strong-ссылок
var strongRef1: Person? = Person(name: "Alice") // Жилец 1 заехал. retain count = 1
var strongRef2 = strongRef1 // Тот же мудак дал копию ключа брату. retain count = 2 (новая strong-ссылка)
strongRef1 = nil // Брат съебал, ключ выбросил. retain count = 1
strongRef2 = nil // И второй съебал. retain count = 0 -> объект деаллоцируется, бульдозер нахуй!
А теперь главные фишки, которые в голове держать надо:
- По умолчанию они все такие. Объявил
var ref = MyClass()— поздравляю, ты только что создал strong-ссылку, даже не зная того. Swift так заботится, сука. - Память сама управляется. ARC — он умный, он считает. Твоя работа — правильно расставлять
weakиunowned, когда нужно, чтобы не было пиздеца. - Циклические ссылки — это ад. Это когда две квартиры (объекта) прописаны друг у друга. У Alice в договоре прописан Bob, а у Bob в договоре прописана Alice. Они оба съехали, но договора-то друг на друга остались! Счётчики никогда не станут нулём, и бульдозер памяти никогда не приедет. Мусор, утечка. От этого спасают
weak(сосед, у которого есть ключ, но он не жилец) иunowned(сосед, который клянётся, что жилец-то есть, но если его нет — краш, пизда).
Вот и вся наука. Главное — следи, чтобы твои объекты не начали друг друга в strong-объятиях душить, а то приедет ARC, посмотрит на эти циклические пляски и скажет: «Ну, ебать, живите тут вместе вечно, мне похуй». И память потечёт.