У меня есть циклическая ссылка. Как я могу создать слабую ссылку в Objective C?

Я нашел это на подобном обсуждении, я думаю, что это было в Reddit: Вебкаст Беркли UC я нашел его самым полезным, начиная с него подкасты все классы от курсов Berkley, таких как Операционные системы и Системное Программирование, Структура и Интерпретация Компьютерных программ, Структур данных и Методологии программирования, среди других.

20
задан outis 19 July 2012 в 02:05
поделиться

3 ответа

Изменить: Поскольку спрашивающий пояснил, что он не использует сборку мусора (iPhone в настоящее время не поддерживает ее), я советую избегать циклов, сохраняя только один из объектов за другим, так же, как если бы вы поступили с делегатом. При использовании свойств используйте для этого «присваивать» вместо «сохранять». Например:

@property (nonatomic,assign) Row *yCoord;

Остальная часть моего ответа относится к «слабым ссылкам» с точки зрения Objective-C 2.0 и GC.


Когда вы работаете со сборкой мусора (10.5+), слабая ссылка создается добавление к объявлению переменной префикса __ weak . Когда вы назначаете эту переменную, GC (если он включен) отслеживает ссылку и автоматически обнуляет ее для вас, если все сильные ссылки на указанный объект исчезнут. (Если GC не включен, атрибут __ weak игнорируется.)

Таким образом, вы можете смело изменить приведенный выше ответ, чтобы улучшить работу со сборкой мусора (в настоящее время на 10.5+ и, возможно, когда-нибудь на iPhone) следующим образом: (См. , связанные с документами Apple .)

@property (nonatomic,assign) __weak Row *yCoord;

Цитата Криса Хансона (где вы можете найти более подробную информацию):

«Путем добавления к объявлению переменной экземпляра префикса __ weak , вы говорите сборщику мусора, что если это единственная ссылка на объект, то этот объект следует считать собираемым ».

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

Примечание: This isn ' t напрямую относится к созданию слабых ссылок, но есть также атрибут __ strong , но поскольку объектные переменные Objective-C по умолчанию являются сильными ссылками, он обычно используется только для необработанных указателей C. к таким вещам, как структуры или примитивы, которые сборщик мусора не будет рассматривать как корни и будет собираться из-под вас, если вы не объявите их сильными. (В то время как отсутствие __ weak может вызвать циклы сохранения и утечки памяти, отсутствие __ strong может привести к потере памяти и действительно странным и коварным ошибкам, которые возникают недетерминированно и могут быть довольно трудно отследить.)

он обычно используется только для необработанных указателей C на такие вещи, как структуры или примитивы, которые сборщик мусора не будет рассматривать как корни и будет собираться из-под вас, если вы не объявите их сильными. (В то время как отсутствие __ weak может вызвать циклы сохранения и утечки памяти, отсутствие __ strong может привести к потере памяти и действительно странным и коварным ошибкам, которые возникают недетерминированно и могут быть довольно трудно отследить.)

он обычно используется только для необработанных указателей C на такие вещи, как структуры или примитивы, которые сборщик мусора не будет рассматривать как корни и будет собираться из-под вас, если вы не объявите их сильными. (В то время как отсутствие __ weak может вызвать циклы сохранения и утечки памяти, отсутствие __ strong может привести к потере памяти и действительно странным и коварным ошибкам, которые возникают недетерминированно и могут быть довольно трудно отследить.)

19
ответ дан 30 November 2019 в 00:19
поделиться

Слабая ссылка - это просто присваивание (если вы не говорите о сборке мусора, которая представляет собой отдельную банку червей, но не страдает от циклов сохранения).

Обычно в Какао, Строка сохранит объекты Блока (путем включения их в NSMutableArray), но Блок не сохранит Строку , каждый из них будет просто сохраните его в ivar (со свойством "assign").

Пока Row осторожно освобождает каждый Блок , прежде чем он будет освобожден (т. е. его ] dealloc должен освободить NSMutableArray, который освободит блоки, пока ни у кого нет указателей на них), тогда все будет освобождено соответствующим образом.

Вы также можете принять меры предосторожности и обнулить ссылку на строку из блоков перед удалением элементов из массива, например:

- (void) dealloc {
    for (Block* b in _blocks) {
        b.row = nil;
    }
    [_blocks release];
    [super dealloc];
}

где _blocks - это ivar, на который ссылается свойство блоков.

4
ответ дан 30 November 2019 в 00:19
поделиться

Просто измените его, чтобы назначить вместо сохранения, больше никаких циклических ссылок.

@interface Block : UIImageView {
  Row *yCoord;
}
@property (nonatomic,assign) Row *yCoord;
@end
8
ответ дан 30 November 2019 в 00:19
поделиться