2009-07-09 10 views
23

Résumé de ma question: NSURLConnection conserve-t-il son délégué?Est-ce qu'un NSURLConnection conserve son délégué?

question détaillée et scénario:

J'ai une classe personnalisée, appelée JsonDownloader qui prend dans une URL et retourne une NSDictionary du JSON que les déclarations d'URL.

Sur une application iPhone, je fais quelque chose comme ça. (La méthode d'initialisation démarre le processus)

- (void)viewDidLoad { 
    JsonDownloder *temp = [[[JsonDownloader alloc] initWithURL:urlString returnDataTo:self]]; 
    [temp release]; 
    [super viewDidLoad]; 
} 

Lorsque le JsonDownloader est fait de télécharger et d'analyse, il effectue un rappel au returnDataTo: objet, dans ce cas, l'objet d'appel.

Cela fonctionne très bien. Même si j'introduis un délai de 30 secondes dans la réponse de mes serveurs Web, le JsonDownloader existe toujours et fonctionne correctement. Mes questions sont les suivantes: Qu'est-ce qui empêche JsonDownloader de dépasser la fin du cycle de l'événement? Je le publie explicitement. Mon sentiment est que NSURLConnection doit faire une retenue sur son délégué, mais je n'ai rien vu dans la documentation. Quelqu'un a une idée?

Répondre

25

Il y a peu de setters qui ne copient ou ne conservent pas une variable qui lui est transmise, de peur que la mémoire de cette variable ne soit réaffectée à quelque chose d'autre quand son compte de retenue atteint zéro.

Cependant, la réponse est OUI, c'est le cas. Un peu de code de test montre le nombre de conserver du délégué monterons

NSLog(@"Retain count before: %d", [self retainCount]); 
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]]; 
NSURLConnection* conn = [NSURLConnection connectionWithRequest:request delegate:self]; 
NSLog(@"Retain count after: %d", [self retainCount]); 

qui produit dans le journal:

Running… 
2009-07-09 02:13:40.516 delegateRetain[45123:a0f] Retain count before: 1 
2009-07-09 02:13:40.525 delegateRetain[45123:a0f] Retain count after: 2 

Debugger stopped. 

Vous pouvez donc voir assez clairement que dans connectionWithRequest:delegate: « soi » est en effet ayant son retenir le compte augmenté +1. Si vous vous sentez courageux et que vous voulez jouer avec les dieux EXC_BAD_ACCESS, ajoutez

[conn dealloc]; 
NSLog(@"Retain count after dealloc: %d", [self retainCount]); 

qui imprimera « 1 », montrant un décrément après dealloc. Cependant, vous aurez une belle Program received signal: “EXC_BAD_ACCESS”. parce que le NSAutoreleasePool va essayer de libérer la connexion et il sera parti;)

+1

Bonne question et bonne réponse. Je luttais avec cela moi-même, mais j'ai décidé d'ajouter [auto-libération] juste après que le délégué a assigné pour égaliser le nombre de retenue. Puisque le moi est délégué dans ma classe, je n'ai vu aucune raison pour que son compte soit augmenté. Si c'est incorrect, quelqu'un me le fera savoir. – jocull

+0

Je veux juste ajouter - merci. The Missing Manual, partie 327. Il mendie la croyance que ce genre de fait important n'est pas mentionné dans la documentation d'Apple. Je me suis dit qu'il était retenu, mais je n'en étais pas sûr, les docs n'en parlent pas et, dans la plupart des cas, les délégués dans les cadres de Cocoa ne sont pas retenus. C'est l'exception. – n13

9

La plupart des délégués propriétés ne sont pas conservés mais affectés pour éviter des références circulaires. Voir this question à ce sujet aussi. Cependant, NSUrlConnection n'a pas de propriété déléguée spécifique. Vous devez spécifier le délégué avec l'initialisation de la connexion. Je pense que c'est la raison pour laquelle il reçoit une retenue, comme l'a montré Dave Martorana.

7

Oui, "La connexion conserve le délégué qui libère le délégué lorsque la connexion est terminée, échoue ou est annulée", conformément à la section Xcode Documentation for -[NSURLConnection initWithRequest:delegate:] sous Considérations spéciales. Voir aussi: NSURLConnection inherent memory leak?

+1

Ok c'est donc une "note" sur NSURLConnection. Cependant, il devrait être mentionné dans la description de la méthode, car c'est plutôt important. – n13

Questions connexes