Объяснение сильного и слабого хранилища в iOS5 - PullRequest
113 голосов
/ 13 февраля 2012

Я новичок в разработке для iOS5 и использую цель-c. У меня проблемы с пониманием разницы между сильным и слабым хранилищем. Я прочитал документацию и другие вопросы SO, но все они звучат одинаково для меня, без дальнейшего понимания.

Я прочитал документацию: Переход на ARC - это ссылки на iOS4 условия сохранения, назначения и выпуска; что меня смущает. Затем я смотрю в Open U CS193p, где он различает сильных и слабых:

Сильный : "держите это в куче, пока я больше не укажу на это"
Слабый : "держите это, пока кто-то еще сильно на него указывает"

Разве два определения не идентичны = если указатель больше не указывает на объект, то освободить память, содержащую объект? Я понимаю концепцию указателей, кучи, выделения или освобождения памяти - но в чем разница между сильным и слабым?

Ответы [ 6 ]

507 голосов
/ 13 февраля 2012

Разница в том, что объект будет освобожден, как только на него не будет указателей strong .Даже если на него указывают слабые указатели, после того как последний сильный указатель исчезнет, ​​объект будет освобожден, а все оставшиеся слабые указатели будут обнулены.

Возможно, приведен пример в порядке.

Представьте, что наш объект - собака, и что собака хочет убежать (быть освобожденной).

Сильные указатели похожи на поводок собаки.Пока у вас есть поводок, привязанный к собаке, собака не убежит.Если пять человек прикрепят свой поводок к одной собаке (пять сильных указателей на один объект), то собака не убежит, пока все пять поводков не отсоединятся.

Слабые указатели, с другой стороны, похожи на маленькиеДети указывают на собаку и говорят: «Смотри! Собака!»Пока собака все еще на поводке, маленькие дети все еще могут видеть собаку, и они все еще будут указывать на нее.Как только все поводки отсоединены, собака убегает независимо от того, сколько на нее указывают маленькие дети.

Как только последний сильный указатель (поводок) больше не указывает на объект,объект будет освобожден, а все слабые указатели будут обнулены.

34 голосов
/ 13 февраля 2012

Разве два определения не идентичны.

Абсолютно нет. Ключевое различие в двух определениях, которые вы указали, заключается в том, что «пока кто-то еще». Это «кто-то еще», который важен.

Обратите внимание на следующее:

__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

Теперь у нас есть два указателя на <some_object>, один сильный и один слабый. Если мы установим strongObject в nil примерно так:

strongObject = nil;

Тогда, если вы будете следовать изложенным правилам, вы зададите себе следующие вопросы:

  1. Сильный: "держи это в куче, пока я не укажу на это"

    strongObject больше не указывает на <some_object>. Так что нам не нужно его хранить.

  2. Слабый: "держите это, пока кто-то еще сильно на него указывает"

    weakObject по-прежнему указывает на <some_object>. Но поскольку никто остальное не указывает на это, это правило также означает, что нам не нужно его хранить.

В результате <some_object> освобождается, и если ваша среда выполнения поддерживает его (Lion и iOS 5 и выше), тогда weakObject будет автоматически установлен на nil.

Теперь рассмотрим, что произойдет, если мы установим weakObject в nil следующим образом:

weakObject = nil;

Тогда, если вы будете следовать изложенным правилам, вы зададите себе следующие вопросы:

  1. Сильный: "держи это в куче, пока я не укажу на это"

    strongObject указывает на <some_object>. Поэтому нам нужно сохранить его.

  2. Слабый: "держите это, пока кто-то еще сильно на него указывает"

    weakObject не указывает на <some_object>.

В результате <some_object> является не освобожденным, но weakObject будет указателем nil.

[Обратите внимание, что все, что предполагает <some_object>, не указывается другой сильной ссылкой где-то еще / каким-либо другим способом «удержания»]

2 голосов
/ 07 сентября 2015

Другой пример: Студент - Object, предполагается, что она / он может закончить (deallocate), если она / он закончила все основные курсы (strong pointers), независимо от того, берет ли она / он дополнительные курсы (weak pointers) ). Другими словами: сильный указатель является единственным фактором освобождения этого Object.

2 голосов
/ 15 августа 2014

Strong

  1. Создает право собственности между свойством и присвоенной ценностью.
  2. Это свойство по умолчанию для свойства объекта в ARC, поэтому оно не позволяет вам беспокоиться о количестве ссылок и автоматически освобождает ссылку.
  3. Это замена для сохранения. Мы используем тогда и только тогда, когда нам нужно использовать как удержание.

Слабое

  1. Создает права собственности между имуществом и присвоенным значением.
  2. Сильный используется на родительском объекте, а слабый - на дочернем объекте, когда родительский объект освобожден, тогда ссылка на дочерний объект также устанавливается на nil
  3. Помогает предотвратить сохранение циклов.
  4. Он не защищает объект, на который ссылаются, при сборке сборщиком мусора.
  5. Слабым по существу присваивается, не сохраняется свойство.
1 голос
/ 18 июля 2017

Я знаю, что довольно поздно опаздываю на эту вечеринку, но я думаю, что важно запутать проблему, указав, что значение «сильных и слабых моделей памяти» зависит от того, говорите ли вы о программном или аппаратном обеспечении.

Для аппаратного обеспечения слабый или сильный указывает, есть ли поддержка последовательной согласованности.

[SC означает, что] ... результат любого выполнения такой же, как если бы операциииз всех процессоров были выполнены в некотором последовательном порядке, и операции каждого отдельного процессора появляются в этой последовательности в порядке, указанном его программой.- Лампорт, 1979

WTF это имеет отношение к памяти?Это означает, что записи в переменные разными процессорами должны рассматриваться в одном и том же порядке всеми процессорами.В оборудовании с сильной моделью это гарантировано.На аппаратном обеспечении со слабой моделью это не так.

Существующие ответы интерпретируют вопрос только с точки зрения моделей памяти программного обеспечения.Аппаратное обеспечение не имеет никакого отношения к программированию.В этом же вопросе упоминается iOS, которая обычно работает на процессорах Arm7.Arm7 имеет слабую модель памяти.Для программистов, привыкших к процессорам с сильной моделью - а это все мы, потому что у x86 и x64 - сильная модель - это ужасная ловушка.Использование bool для сигнализации о выходе другого потока прекрасно работает в сильной модели.Тот же код на Arm не работает вообще, если вы не пометите флаг как изменчивый, и даже тогда он будет ошибочным.

Хотя это правда, что Arm8 + меняет это полностью с явной поддержкой приобретения / выпуска, устаревшее программное обеспечение не использует эту поддержку.Устаревшее программное обеспечение включает в себя все три телефонные ОС и все, что на них работает, а также компиляторы и библиотеки до их обновления.

Для расширенного изучения этой темы я отсылаю вас к неподражаемому Herb Sutter .

1 голос
/ 13 февраля 2012

Нет, они не идентичны, но очень разные.Вы используете сильный, только если вам нужно сохранить объект.Вы используете слабый в любом другом случае, с тем преимуществом, что вы можете знать, если объект был удален из кучи, потому что никто не хранит его.

...