2010-01-31 5 views
1

J'ai une question sur le fonctionnement des variables d'instance et quand utiliser @property. Voici un exemple de fichier d'interface avec lequel je travailleQuestion sur ivars et @ property's sur l'iPhone

@interface PackageModel : NSObject { 
    NSString *tracking; 
    NSString *carrier; 
    NSString *status; 
    NSMutableDictionary *events; 

    // Connection ivars 
    NSMutableData *receivedData; 

    // Parsing ivars 
    int tagLevel; 
    NSMutableArray *tagTree; 
    NSString *parentTag; 
    NSString *currentTag; 
} 

@property (nonatomic, retain) NSMutableData *receivedData; 

- (id)initWithTrackingString:(NSString *)string; 
- (void)getPackageDataWithEvents; 
- (void)printMe; 

@end 

Comment puis-je y accéder dans le code du fichier. Puis-je avoir accès à un suivi, le transporteur et l'état dans les méthodes de cette classe juste en utilisant quelque chose comme

tracking = [[NSString alloc] initWithString:@"Hello World"]; 

En outre, quelles variables doivent être mises en dealloc? Seules les variables que j'ai dans la @ propriété/@ synthétisent? Ou dois-je libérer toutes les variables d'instance dans la méthode dealloc.

Je cherche simplement à savoir comment les variables d'instance fonctionnent en Objective-C. Merci.

Répondre

3

@property Les déclarations ne sont rien de plus que des méthodes getter et setter générées par le compilateur. C'est tout. Juste les méthodes. Évidemment, vous devez obtenir et mettre quelque chose, donc nous créons l'ivar qui va avec les getters et les setters. Dans votre exemple ci-dessus, votre compilateur génère:

- (NSMutableData *) receivedData; 
- (void) setReceivedData:(NSMutableData *)newReceivedData; 

Le getter renvoie la valeur dans la variable d'instance receivedData, et le poseur change la valeur de la variable d'instance receivedData.

(Note: avec le moteur d'exécution 64 bits, vous pouvez ignorer déclarer la variable d'instance, mais je l'aime encore le mettre en juste être explicite)

Quant à ce que vous devez faire dans votre méthode dealloc , vous devez libérer les variables d'instance qui ont été retain ed ou copy ed. Donc, dans votre exemple, vous devrez faire [receivedData release]; dans votre méthode dealloc, car lorsque vous définissez le receivedData ivar, vous avez conservé la nouvelle valeur (c'est ce que le retain signifie sur la ligne @property). Si vous ne spécifiez pas retain ou copy dans la déclaration @property, la valeur par défaut est assign et vous n'avez rien à faire. Au-delà, vous devrez libérer toutes les autres variables d'instance que vous avez vous-même conservées (c'est-à-dire, pas à travers un setter @property (retain)).

Pour votre dernière question, oui, vous pouvez juste faire:

tracking = [[NSString alloc] initWithFormat:@"Hello, %@!", @"world"]; 

l'intérieur de votre propre classe, vous avez un accès direct à toutes vos propres variables d'instance (et toutes les Ivars protégées et publiques de vos super-classes).

+0

Maintenant, pour la currentTag et parentTag j'y ai défini, je les mettre dans les méthodes de délégué NSXMLParser par currentTag = qName. Je n'ai pas besoin de les libérer dans le dealloc parce qu'ils ne sont que des pointeurs vers ces autres cordes, n'est-ce pas? Mais, si je les ai fait @property, je devrais les libérer correctement? – rickharrison

+0

rickharrison: '@ property' n'a rien à voir avec si vous possédez l'objet. Peu importe * comment * vous êtes venu le posséder; Si vous le possédez, vous devez le libérer. Voir les règles de gestion de la mémoire: http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html –

0

Un avantage de l'utilisation de @ property/@ syntehsize est qu'il vous pousse à utiliser des méthodes d'accès pour les ivars. Cela vous aide à améliorer la gestion de la mémoire. Sur l'iPhone, est-ce que vous devez être conscient de retenir les comptes pour deux grandes raisons: 1. Gardez l'utilisation de la mémoire vers le bas. 2. Évitez les accidents. Lorsque vous accédez directement à ivars, vous risquez d'oublier de conserver une variable, puis d'y accéder plus tard pour découvrir qu'elle a été libérée. Ou au contraire, vous avez oublié de libérer une variable, et très vite vous avez accumulé tellement de mémoire que l'iPhone OS dit à votre application de se terminer.

L'utilisation de méthodes d'accès, même à l'intérieur de la classe, est généralement une bonne idée. Le seul endroit où je place normalement les ivars directement est dans la méthode init de la classe. Je libère également tous mes ivars dans la méthode dealloc.

1

Oui, c'est une question très vaste. Je vous recommande fortement de lire le Objective-C Primer d'Apple et leur full reference to the language. En tant que starter, vous demandez: "Comment puis-je y accéder dans le code du fichier?" Vous ne spécifiez pas quel fichier. À l'intérieur du @implementation de PackageModel, vous pouvez simplement vous référer aux variables d'instance comme vous le faites dans votre exemple de suivi. Vous ne pouvez pas y accéder facilement depuis d'autres classes.

Si, cependant, vous les faites @properties et @synthesize eux, vous pouvez y accéder dans la classe elle-même comme self.tracking. De plus, vous pouvez également y accéder depuis d'autres classes.

PackageModel *model = [[PackageModel alloc] init]; 
model.receivedData = [NSMutableData data]; 

Un autre avantage des propriétés est qu'elles peuvent gérer la gestion de la mémoire pour vous. Quand c'est fait correctement, vous n'avez vraiment pas besoin de vous préoccuper des retenues et des libérations. Cette propriété receivedData de votre classe PackageModel libère automatiquement tous les objets précédemment conservés avant d'affecter les nouvelles données. C'est glorieux. Cela arrive parce que le compilateur "synthétise" automatiquement les setters et les getters, puis les appelle pour des accès via l'opérateur dot. Une note finale est que ces setters et getters sont automatiquement protégés par un bloc @synchronize qui garantit que les opérations se font de manière atomique (et qu'un deuxième thread ne peut pas perturber l'activité à mi-chemin). Ceci est largement inutile sur un iPhone et provoque une quantité décente de frais généraux, de sorte qu'il vous appartient de déclarer toutes vos propriétés en tant que nonatomic en plus de vos autorisations de lecture/écriture et schéma de gestion de la mémoire.

1

Quelque chose ne sont pas couverts est que votre dernière ligne de code pourrait être:

tracking = @"Hello World"; 

Le « @ » est essentiellement la création de l'objet de chaîne pour vous.