Как избежать циклического удержания с помощью ARC (сильный / слабый), изучая некоторые основы - PullRequest
4 голосов
/ 30 марта 2012

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

Допустим, у меня есть UITableViewController с источником данных NSArray объектов MyObject. Поэтому в моем UITableViewController я объявляю свой источник данных как:

@property (strong, nonatomic) NSArray *dataSource;

Затем, после того как я коснулся ячейки, я хочу открыть новый вид, который показывает подробный вид чего-либо, используя MyObject этой ячейки. Итак, в новом UIViewController у меня есть это:

@property (strong, nonatomic) MyObject *myObject;

Теперь в UITableViewController при касании ячейки:

MyObject *myObject = [[self dataSource] objectForIndex:[indexPath row]];
NewView *view = [[NewView alloc] initWithMyObject:myObject];
// ... push onto nav controller, etc

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

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

Ответы [ 2 ]

4 голосов
/ 30 марта 2012

Я думаю, что вам нужно понять, как работает дуга.

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

Это работает путем добавления счетчика ссылок в объект, поэтому, когда вы делаете это:

@property (strong, nonatomic) MyObject *myObject;

вы создаете СИЛЬНЫЙ указатель для myObject (не для объекта).

но когда вы сделаете это

MyObject *myObject = [[self dataSource] objectForIndex:[indexPath row]];

вы делаете этот указатель увеличивающим счетчик ссылок на все, что у вас есть в указанном индексе из этого источника данных.

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

О вашей заботе о взглядах.

Представления, созданные в конструкторе интерфейса, имеют свои элементы, объявленные внутри с помощью сильных указателей. Это когда вы хотите использовать слабую ссылку. Когда вы добавляете свой собственный IBOutlet к элементу в представлении, рекомендуется сделать его слабым. Если вы думаете о причине логически, это в основном означает, что вам не нужен этот элемент конструктора интерфейса, поскольку вы хотите, чтобы он выжил только до освобождения viewcontroller.

Когда вы обычно сталкиваетесь с циклами сохранения, это когда у объекта есть дочерний объект, а у этого дочернего объекта есть STRONG ссылка на его родителя.

это:

Объект A создает объект B с указателем strong

Объект B указывает на объект A с сильным указателем

A сохранит B живым, а B сохранит A живым.

Эта страница объяснит вам некоторые основные вещи о том, как избежать такого рода вещей:

http://cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html

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

Сначала получите указатель от Представления 1 к Представлению 2 (может быть сильным или слабым в зависимости от того, кто должен поддерживать представление 2 живым, если он от IB Builder, он должен быть слабым, если программно он должен быть сильным)

Во-вторых, создайте свойство в представлении 2 (@property (strong, nonatomic) MyObject * myObject;)

теперь это так же просто, как:

Self.view1Pointer.myObject = self.myOtherObject;

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

Вы не создадите цикл сохранения, просто для подсчета ссылок с этого объекта установлено значение 2.

Примечание: Когда представление освобождается, все его указатели устанавливаются на ноль, поэтому любой объект, на который они указывают, будет уменьшать свой счетчик ссылок. Если оно достигает 0, оно освобождается. (в предыдущем случае myobject будет 1, потому что другое представление все еще указывает на него).

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

Подробнее о дуге можно узнать здесь:

http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1

4 голосов
/ 30 марта 2012

Это не цикл сохранения. Это прекрасный способ делать вещи. Экземпляр MyObject строго не ссылается ни на одного из его владельцев, поэтому, когда последний из этих владельцев в конечном итоге будет освобожден, объект тоже будет.

...