Comment libérer l'attribut qui est protocole?
-
05-07-2019 - |
Question
Je travaille depuis un certain temps pour le développement d’un iPhone. Pour la première fois, je suis tellement surpris de la gestion de la mémoire dans Objective-c :). mais maintenant je l'ai un peu.
La question est que j’utilise parfois le protocole comme attribut d’une classe, car je pense que sa définition est très similaire à "interface" en C # ou en Java. comme ci-dessous.
@protocol Shield
...
@end
// Interface
@interface Dragon {
id<Shield> shield
NSString * name;
}
@property (nonatomic,retain) id<Shield> shield;
@property (nonatomic,retain) NSString * name;
@end
mais je libère toujours tout objet attribut dans la méthode dealloc (). comme ci-dessous.
-(void)dealloc {
[name release];
[shield release]; // <--- Totally impossible. xcode said '-release not found in protocol'
[super dealloc];
}
Comme vous le voyez, je ne pouvais pas publier le protocole. Cela me causerait-il donc un problème de mémoire future? Avez-vous un autre moyen de gérer cette solution pour me conseiller?
La solution
Vous devez définir votre protocole comme adhérant au protocole NSObject
, comme suit:
@protocol Shield <NSObject>
...
@end
C'est simple quand on sait comment faire! ; -)
Éditer: vous avez également raison: les protocoles en Objective-C sont équivalents aux interfaces en Java et en C #.
Autre modification: cela peut vous paraître étrange, mais Objective-C autorise la création de plusieurs objets racine. Vous ne pouvez donc pas garantir que chaque objet descendra de release
. Étant donné que <NSObject>
est une méthode <=>, vous devez définir votre protocole comme adhérant également au protocole <=> avant de pouvoir être sûr qu'il sera en mesure de répondre à la méthode <=>.
Autres conseils
1-la bonne chose à faire au lieu de [libération du bouclier] est en train de se mettre
self.shield = nil;
2-Changez aussi
@property (nonatomic,retain) id<Shield> shield;
à
@property (nonatomic,assign) id<Shield> shield;
Alors vous allez bien.
modifier:
La raison pour laquelle vous évitez de conserver délégués est que vous devez éviter une boucle de retenue:
A crée B A se définit comme B déléguer & # 8230; A est libéré par son propriétaire
Si B avait retenu A, A ne serait pas libéré, comme B possède A, donc A dealloc ne serait jamais appelé, provoquant des fuites à la fois pour A et pour B.
Ne vous inquiétez pas pour le départ de A b / c il possède B et s'en débarrasse ainsi dans dealloc.
veuillez consulter la référence de la classe uitableview pour un exemple de déclaration de protocole:
@property (nonatomic, assign) id < UITableViewDelegate & Gt; déléguer