Безопасно ли объявлять все свойства слабыми, чтобы избежать затрат на подсчет ссылок?
Это проблематично по двум причинам. Во-первых, weak
не избегает подсчета ссылок. На самом деле он выполняет больше бухгалтерии, чем strong
. См. Много накладных расходов для слабого свойства? для хорошего обсуждения этого.
Далее, это неправильно, потому что weak
и strong
означают разные вещи, которые нельзя взаимозаменять. Как отмечает MartinM, если вы сделаете ваши свойства weak
, они просто исчезнут, как только вы назначите их, если их больше ничего не удержит.
Если не безопасно, то почему это не безопасно?
Это абсолютно безопасно. Это просто не сработает. Ваша программа будет иметь четко определенное поведение и не должна падать из-за пометки всех ваших свойств weak
. Большинство ваших свойств будет просто nil
. Если бы вы использовали unsafe_unretained
вместо weak
, тогда вы избежали бы некоторых накладных расходов на подсчет ссылок, и ваша программа, как правило, зависала (поскольку объекты все равно будут уничтожены, указатели просто станут недействительными).
Каким будет счетчик ссылок str?
Это не значимый вопрос, даже если кажется, что он один. В данном конкретном случае ответом является 9 223 372 036 854 775 807, потому что это всегда счетчик сохранения статической строки, поскольку статические строки нельзя уничтожить и игнорировать вызовы сохранения / освобождения. (Это значение NSNotFound
в ObjC. Я считаю, что раньше оно возвращало 1 152 921 504 606 846 975, но мои тесты показывают, что оно изменилось.)
Но в общем случае это может быть что угодно в данный момент времени. И то, что происходит в данный момент времени по сравнению с концом цикла событий (когда истощается автозапуск), может сильно отличаться. Не гонитесь за сохранением значений счета. Они всегда будут лгать тебе. Создайте сильные ссылки на вещи, которые вас волнуют. Создавайте слабые ссылки только тогда, когда они нужны вам для специальных целей.
Сохранять счетчики - это внутренняя деталь реализации. До ARC они вводили в заблуждение до бесполезности . Начиная с ARC, они как бы спрашивают «к каким инструкциям по сборке это будет компилироваться». Это важно, но это зависит от всего остального в программе и от того, как она компилируется.
Если у вас есть конкретная проблема с производительностью, связанная с управлением памятью, то есть методы для решения этой проблемы в каждом конкретном случае, и StackOverflow может вам помочь. Но ARC чрезвычайно хорош в оптимизации управления памятью. Пусть это сделает свое дело.