Как освободить атрибут, который является протоколом? - PullRequest
1 голос
/ 26 ноября 2009

Я некоторое время работаю над разработкой для iPhone. Впервые я так удивился управлению памятью в target-c :). но теперь я понял это немного.

Вопрос в том, что иногда я использую протокол в качестве атрибута класса, потому что я думаю, что его определение очень похоже на «интерфейс» в C # или Java. как показано ниже.

@protocol Shield
   ...
@end

// Interface
@interface Dragon {
    id<Shield> shield
    NSString * name;
}

@property (nonatomic,retain) id<Shield> shield;
@property (nonatomic,retain) NSString * name;

@end

но я всегда освобождаю любой объект атрибута в методе dealloc (). как показано ниже.

-(void)dealloc {
   [name release];
   [shield release];  // <--- Totally impossible. xcode said '-release not found in protocol'
   [super dealloc];
 }

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

Ответы [ 2 ]

8 голосов
/ 26 ноября 2009

Вы должны определить свой протокол как соответствующий протоколу NSObject, например:

@protocol Shield <NSObject>
   ...
@end

Это просто, когда знаешь как! ; -)

Редактировать: Кроме того, вы правы - протоколы в Objective-C эквивалентны интерфейсам в Java и C #.

Другое редактирование: вам может показаться странным, что это необходимо сделать, но Objective-C допускает наличие нескольких корневых объектов, поэтому вы не можете гарантировать, что каждый объект будет происходить с NSObject. Поскольку release - это метод NSObject, вы должны определить свой протокол как соответствующий протоколу <NSObject>, прежде чем сможете быть уверены, что он сможет ответить на метод release.

1 голос
/ 26 ноября 2009

1 - вместо [снятия щита] нужно установить

self.shield = nil;

2-также изменить

@property (nonatomic,retain) id<Shield> shield; 

до

@property (nonatomic,assign) id<Shield> shield;

Тогда ты в порядке.

редактирование:

Причина, по которой вы избегаете сохранения Делегаты в том, что вам нужно избегать сохранить цикл:

A создает B A устанавливает себя как B's делегат ... A выпущен его владельцем

Если бы B сохранил A, A не был бы выпущен, поскольку B владеет A, таким образом, A's Deloloc никогда бы не вызвали, вызывая утечку как A, так и B.

Тебе не стоит беспокоиться об уходе б / с владеет Б и таким образом избавляется от него в деллок.

Почему делегатам Objective-C обычно присваивается свойство, а не сохраняется?

см. Ссылку на класс uitableview для примера объявления протокола:

@ свойство (неатомное, назначить) id делегат

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...