Слабые и сильные ссылки ARC с розетками и набором розеток?

Я хотел бы получить больше информации о ARC и слабой и сильной ссылке:

На самом деле, если у меня есть:

@interface
@property (weak) IBOutlet UIButton * button
@property (weak) UIView *subview
@end

@implementation

-(BOOL) viewDidLoad
{
    UIView *aSubView= [[UIView alloc]....];
    [self.view addSubview:aSubview];
    self.subview = aSubview;
}

Это нормально иметь слабую ссылку на кнопку, потому что ее супервизор имеет сильную ссылку на нее.

Теперь я добавляю UIView программно, я также ставлю слабую ссылку, потому что, когда я добавлю этот subView в superview, будет сильная ссылка. Первый вопрос: хороший ли это метод?

Теперь мои настоящие проблемы связаны со вторым исходным кодом с коллекцией. Что я могу положить с IBOutletCollection?

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

@property (?) IBOutletCollection .....
@property (?) NSArray *subviews

-(BOOL) viewDidLoad
{
    ?
}

person user2907496    schedule 24.10.2013    source источник
comment
Вы должны посмотреть, что такое циклическая ссылка ARC, чтобы помочь вам понять это. У вас может быть столько сильных ссылок, сколько вы хотите, если вы не создаете циклическую ссылку (также называемую циклом сохранения). Так что вполне нормально, если ваши свойства будут strong вместо weak; на самом деле это обычное дело, если вы удаляете подпредставление из одного места и позже добавляете его в другое суперпредставление.   -  person Aaron Brager    schedule 24.10.2013


Ответы (3)


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

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

Ваш NSArray подпредставлений должен быть строгой ссылкой, иначе массив будет освобожден. То же самое и с IBOutletCollection, который на самом деле является просто массивом, поддерживаемым системой.

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

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

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

person Duncan C    schedule 24.10.2013
comment
Так что мне нужно очистить объект от моего NSArray, но где мне это сделать, didReceiveMemoryWarning и viewDidDisappear? - person user2907496; 24.10.2013

На ваш первый вопрос: да, это рекомендуемая стратегия для свойств подпредставления. Что касается второго вопроса, я не совсем уверен, что вы спрашиваете. Вот хороший учебник по IBOutletCollection, если вы ищешь. Если нет, уточните, в чем проблема с IBOutletCollection.

person RyanR    schedule 24.10.2013

1) Когда вы программно добавляете подвид, вы можете сохранить слабую ссылку как свойство в вашем контроллере представления.

2) IBOutletCollection фактически удаляется препроцессором и ничего не значит для компилятора. Это просто подсказка в XCode о том, что со свойством связана коллекция выходов.

3) Вот страница, на которой рассказывается об использовании NSArray для хранения слабых ссылок:

NSArray слабых ссылок (__unsafe_unretained) на объекты под ARC

person godel9    schedule 24.10.2013