2009-11-03 4 views
2

Dans un fichier global.h Je déclare ensuite plus tardQuestion sur les pointeurs en Objective-C

dataManager *IdataManager; 

lorsque le programme initialise I allouer et initialiser la variable, et l'utiliser dans plusieurs vues différentes comme un moyen d'accéder à un ensemble des données qui sont téléchargées lorsque l'application démarre.

Récemment, j'ai remarqué quand je tire l'un de mes points de vue, fermez-le, puis l'ouvrir à nouveau, je reçois un plantage lorsque j'essaie d'accéder à la IdataManager globale.

Je suis finalement arrivé à la conclusion que son contenu était en train d'être publié d'une manière ou d'une autre par la vue qui était désinitialisée. Je regardais le seul endroit que j'utilisais la variable:

CCandidate *currentCandidate = [IdataManager CurrentCandidate]; 

Je changé ceci à dire:

CCandidate *currentCandidate = [[IdataManager CurrentCandidate] retain]; 

Je ne savais pas comment le mot-clé à retenir travaillé, mais il semblait comme si le vue vraiment libérait mes données, je devrais préciser dans la création de ce pointeur qu'il devrait être conservé.

Cela a corrigé le crash, mais je ne comprends pas vraiment pourquoi cela est arrivé. Est-ce que objective-c libère toujours les pointeurs que vous avez créés lorsque vous lui libérez le propriétaire? J'étais sous l'impression que je stockais simplement une adresse mémoire et que je lui donnais le nom currentCandidate.

CCandidate.h:

#import <Foundation/Foundation.h> 


@interface CCandidate : NSObject { 
int ID; 
NSString* FName; 
NSString* MName; 
NSString* LName; 
NSString* FullName; 
NSString* DOB; 
NSString* Occupation; 
NSString* Employer; 
NSString* Phone; 
NSString* Fax; 
NSString* Email; 
NSString* Website; 
NSString* Party; 
NSString* TwitterUName; 
NSString* TwitterHashTag; 
NSString* Biography; 
NSString* BiographyLink; 
NSString* co; 
NSString* cb; 
NSString* uo; 
NSString* ub; 

} 

- (id) init; 

@property (nonatomic, assign) int ID; 
@property (nonatomic, retain) NSString* FName; 
@property (nonatomic, retain) NSString* MName; 
@property (nonatomic, retain) NSString* LName; 
@property (nonatomic, retain) NSString* FullName; 
@property (nonatomic, retain) NSString* DOB; 
@property (nonatomic, retain) NSString* Occupation; 
@property (nonatomic, retain) NSString* Employer; 
@property (nonatomic, retain) NSString* Phone; 
@property (nonatomic, retain) NSString* Fax; 
@property (nonatomic, retain) NSString* Email; 
@property (nonatomic, retain) NSString* Website; 
@property (nonatomic, retain) NSString* Party; 
@property (nonatomic, retain) NSString* TwitterUName; 
@property (nonatomic, retain) NSString* TwitterHashTag; 
@property (nonatomic, retain) NSString* Biography; 
@property (nonatomic, retain) NSString* BiographyLink; 
@property (nonatomic, retain) NSString* co; 
@property (nonatomic, retain) NSString* cb; 
@property (nonatomic, retain) NSString* uo; 
@property (nonatomic, retain) NSString* ub; 

@end 

CCandidate.m:

#import "CCandidate.h" 


@implementation CCandidate 
@synthesize ID; 
@synthesize FName; 
@synthesize MName; 
@synthesize LName; 
@synthesize FullName; 
@synthesize DOB; 
@synthesize Occupation; 
@synthesize Employer; 
@synthesize Phone; 
@synthesize Fax; 
@synthesize Email; 
@synthesize Website; 
@synthesize Party; 
@synthesize TwitterUName; 
@synthesize TwitterHashTag; 
@synthesize Biography; 
@synthesize BiographyLink; 
@synthesize co; 
@synthesize cb; 
@synthesize uo; 
@synthesize ub; 

-(id) init { 
self = [super init]; 
ID = -1; 
return self; 
} 

@end 
+0

Apprenez à écrire une méthode d'initialisation correcte: http://www.mikeash.com/?page=pyblog/the-how-and-why-of-cocoa-initializers.html –

+0

Comment initialisez-vous le global? variable? Je pense que cela pourrait être que cette variable est autoreleased. –

+0

Après un rappel connectionDidFinishLoading, j'ai défini: IdataManager = [[dataManager alloc] initWithData: receivedData]; – Jameson

Répondre

1

Vous écrivez qu'il se bloque lorsque vous accédez à IdataManager. C'est pas vrai. Vous êtes programme se bloque lorsque vous essayez d'accéder à l'objet CurrentCandidate que vous avez reçu l'aide de la ligne suivante:

// read about naming methods here: http://cocoadevcentral.com/articles/000082.php 
CCandidate *currentCandidate = [IdataManager CurrentCandidate]; 

Je suppose que vous êtes quelque part la libération currentCandidate vous ne devriez pas. Il fonctionne la première fois parce que vous récupérez un objet autoreleased (vous ne doit pas libérer ces vous-même!).

Voici comment il va:

Première:

  1. Get autoreleased currentCandidate.
    == conserver le nombre 2

  2. < votre code >

  3. [currentCandidate release] ou [currentCandidate autorelease]
    conserver le nombre == 1

  4. < votre code >

  5. Tous les objets à libération automatique sont libérés.
    nombre == conservent 0

  6. currentCandidate sera désallouée.

Deuxième temps:

  1. Get autoreleased currentCandidate. C'est un objet invalide qui a déjà été désalloué. -> CRASH.

Si [IdataManager CurrentCandidate] ne le fait pas retour d'un objet autoreleased comme il se doit, mais plutôt que le pointeur sur le membre de IdataManager, le code se bloque plus tard lors de l'accès currentCandidate.

Le fait que l'ajout retain aide s'avère que vous libérez currentCandidate quelque part. Soit directement, via autorelease ou bien un autre algorithme. Toutes les classes de Apple seulement libérer des objets qu'ils ont conservés plus tôt. Quelque part dans votre code, il y a un déséquilibre retain/release.

2

Vous libérez probablement currentCandidate à la fin de votre méthode, ou sur désaffecter votre point de vue. Puisque vous n'avez pas conservé l'objet currentCandidate, vous ne devez pas le libérer non plus!

Balayez votre code pour quelque chose des sortes: [Communiqué currentCandidate]

Assurez-vous de lire sur la gestion de la mémoire. C'est assez important.

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html

+0

La première chose que j'ai faite a été de vérifier si j'aurais pu publier currentCandidate, il ne sera pas publié. – Jameson

+0

Désolé, il est en train de se libérer, mais il n'y a pas de code qui le libère, ça se passe quand je libère la vue, qui ressemble à ça: - (void) dealloc { [super dealloc]; } – Jameson

+1

Pouvez-vous nous donner le message d'erreur exact que Xcode donne? Il semblerait que CurrentCandidate ne soit pas retenu en premier lieu. Pouvez-vous publier le code qui initie CurrentCandidate dans IdataManager? Avez-vous activé la récupération de place? (ne devrait pas importer, mais encore!) "Paramètres du projet -> Construire -> recherche de 'déchets'" – nash

Questions connexes