Почему в некоторых торговых точках сделаны сильные ссылки, даже жесткие документы указывают, что выходы должны быть слабыми ссылками

Привет, я новичок в программировании на iOS. Я знаю, какая сильная и слабая ссылка. Но я смущаюсь, какой тип ссылки использовать, когда мне приходится иметь дело с выходами. Пройдя через документацию, в которой говорится, что

Выходы обычно должны быть слабыми, за исключением тех, которые принадлежат файловому владельцу, для объектов верхнего уровня в файле nib (или в iOS, сценае раскадровки), который должен быть сильным.

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

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

@interface AboutViewController : UIViewController

@property (nonatomic, strong) IBOutlet UIWebView *webView;

@end

Код:

@property (nonatomic, strong) IBOutlet UIWebView *webView;

говорит, что наш AboutViewController имеет объект UIWebView.

Но зачем нам нужна ссылка здесь для объекта UIView? Как говорится в документе, это не должно быть слабой ссылкой?

Также объясните в заявлении документации, которое я привел выше, что означает Владелец файлов для объектов верхнего уровня.

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

Ответ 1

Что использовать для элементов верхнего уровня без верхнего уровня - сильных или слабых - зависит от того, как вы собираетесь использовать свои выходы. Если у вас слабая ссылка

@property (nonatomic, weak) IBOutlet UIWebView *webView;

после вызова метода

[webView removeFromSupeview];

ваш webView будет равен нулю, и восстановить UIWebView будет невозможно, просто добавив

[self.view addSubview:webView];

Если это вам подходит - лучше использовать слабый, потому что вы освободите память WebView, когда вам это не понадобится.

С другой стороны, в случае ссылки strong после

[webView removeFromSupeview];

WebView по-прежнему будет иметь referenceCount > 0, и webView будет освобожден только в том случае, если владелец явно освободит его

self.webView = nil;

или в папке владельца

- (void)dealloc

вместе с самим владельцем.

Обычно нет разницы, если у вас есть статический графический интерфейс. Если вы хотите удалить (не скрывать), некоторые представления добавить возможность добавлять их позже - следует использовать сильные ссылки.

Объекты верхнего уровня должны оставаться сильными. Как

@property(nonatomic,retain) UIView *view;

в UIViewController.

Ответ 2

Как правило, не рекомендуется использовать сильную ссылку вместо слабого в случае таких точек. И в некоторых случаях вам нужна сильная ссылка.

Идея состоит в том, что что-то должно постоянно ссылаться на объект, или оно может исчезнуть. Если объект является представлением, являющимся подвидным для другого представления, то этот супервизор будет содержать ссылки на него, поэтому вы можете использовать слабую ссылку. Но если вы собираетесь сделать что-то еще с этим видом, например, удалить из него супервизор по какой-либо причине (возможно, повторно использовать его в другом месте или что-то еще), тогда вы захотите использовать сильное свойство, чтобы всегда что-то сильно держит его.

Что касается проблемы с файловым владельцем, то из-за того, что объект верхнего уровня (скорее всего, вид) не имеет надстройки для него, так что вам нужно использовать сильное свойство, чтобы вы держались за него.

Ответ 3

Простой ответ заключается в том, что если вы не поддерживаете iOS 5, выходы должны всегда быть сильными.

Цель слабых выходов заключалась в том, что в iOS5, если система выгрузила представление контроллера представления для сохранения памяти, любые выходы, указывающие на подпункты, будут автоматически выпущены.

В iOS 6 и более поздних версиях система никогда не выгружает представление контроллера представления (viewDidUnload никогда не вызывается), потому что Apple нашла способ освободить большую часть памяти, используемой представлением, не отпуская самого представления.

Следовательно, выходы в контроллере представления обычно не должны отпускаться до тех пор, пока сам контроллер представления не будет выпущен, и в этот момент ARC все равно очистит все розетки.

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

Ответ 4

Цитата из Apple Руководство по программированию ресурсов,

Каждый раз, когда вы запрашиваете класс NSBundle или NSNib для загрузки файла nib, базовый код создает новую копию объектов в этом файле и возвращает их вам. Вам необходимо убедиться, что вы сохраняете новый график объектов до тех пор, пока это необходимо, и отмените его, когда вы закончите с ним. Обычно вам нужны сильные ссылки на объекты верхнего уровня, чтобы гарантировать, что они не будут освобождены; вам не нужны сильные ссылки на объекты, расположенные ниже на графике, потому что они принадлежат их родителям, и вы должны свести к минимуму риск создания сильных эталонных циклов.

В случае каркасных классов, таких как UIViewController, объект верхнего уровня для файла NIB является свойством view. Если вы зарегистрируете documentation, оно объявляется как retain (похожее на strong).

@property(nonatomic, retain) UIView *view

Таким образом, любые подзоны к этому контейнеру view должны автоматически принадлежать ему. Если вы теперь объявляете эти выходные объекты subview как strong, они создадут цикл strong и вызовут утечку памяти, когда среда попытается очистить контейнер view. Чтобы избежать этих сильных циклов, все объекты subviews (или объекты верхнего уровня) должны быть объявлены как weak.

Когда вы можете объявить IBOutlet как strong

Розетки должны быть изменены на сильные, когда розетка должна считаться принадлежащей указанному объекту:

  • Как указывалось ранее, это часто происходит с объектами верхнего уровня файлов Owner в файле nib, которые часто считаются владельцами файлов.
  • В некоторых ситуациях вам может понадобиться объект из файла nib, который существует вне его исходного контейнера. Например, у вас может быть выход для представления, которое может быть временно удалено из его первоначальной иерархии представлений и поэтому должно поддерживаться независимо.

Вам нужно проверить свой код, если объект webView подходит для case2, как указано выше. Если это не урок, это неправильно, и на самом деле это должно быть weak.

Надеюсь, что это поможет!