Como liberar atributo que é um protocolo?
-
05-07-2019 - |
Pergunta
Eu trabalho para o desenvolvimento do iPhone por um tempo. Primeira vez, eu tão surpreso com memória de gestão em Objective-C :). mas agora eu entendi um pouco.
A questão é, em algum momento, eu uso o protocolo como um atributo de uma classe, porque eu acho que a sua definição muito semelhante ao 'interface' em C # ou Java. como abaixo.
@protocol Shield
...
@end
// Interface
@interface Dragon {
id<Shield> shield
NSString * name;
}
@property (nonatomic,retain) id<Shield> shield;
@property (nonatomic,retain) NSString * name;
@end
mas eu sempre liberar qualquer objeto de atributo no método dealloc (). como abaixo.
-(void)dealloc {
[name release];
[shield release]; // <--- Totally impossible. xcode said '-release not found in protocol'
[super dealloc];
}
Como você pode ver, eu não poderia liberar o protocolo. Então seria este problema de memória me futura causa? Você tem outra maneira de lidar com esta solução para o conselho mim?
Solução
Você precisa definir o seu protocolo de adesão ao protocolo NSObject
, como este:
@protocol Shield <NSObject>
...
@end
É simples quando você sabe como! ; -)
Edit: Além disso, você está correto - protocolos em Objective-C são equivalentes às interfaces em Java e C #
. Outro edit: Pode parecer-lhe estranho ter que fazer isso, mas Objective-C permite vários objetos raiz, para que você não pode realmente garantia de que cada objeto descerá do NSObject
. Desde release
é um método NSObject
, você tem que definir o seu protocolo como também aderir ao protocolo <NSObject>
antes que você pode ter certeza que vai ser capaz de responder ao método release
.
Outras dicas
1-a coisa apropriada a fazer em vez de [liberação escudo] é a criação
self.shield = nil;
2 também mudar
@property (nonatomic,retain) id<Shield> shield;
para
@property (nonatomic,assign) id<Shield> shield;
Em seguida, você está bem.
edit:
A razão que você evite de retenção delegados é que você precisa para evitar uma reter loop:
A cria B A define-se como B do delegar ... Um é liberado pelo seu proprietário
Se B tinha retido A, A não seria lançado, como B é dono A, assim, de um dealloc nunca seria chamado, fazendo com que ambos A e B a vazar.
Você não deve se preocupar com um indo embora b / c que possui B e, assim, se livrar dele em dealloc.
Por que Objective delegados -C normalmente dada a atribuir propriedade em vez de reter?
consulte referência de classe uitableview para uma declaração exemplo protocolo:
@property (nonatomic, atribua) id