2009-07-09 10 views
23

Riassunto della mia domanda: NSURLConnection conserva il proprio delegato?Un NSURLConnection mantiene il proprio delegato?

domanda dettagliata scenario:

ho una classe personalizzata, denominata JsonDownloader che si prende in un URL e restituisce un NSDictionary del JSON che i rendimenti URL.

Su un'app per iPhone, faccio qualcosa del genere. (Il metodo init prende il via l'intero processo)

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

Quando il JsonDownloader è fatto il download e l'analisi, si esegue un callback per l'returnDataTo: oggetto, in questo caso, l'oggetto chiamante.

Questo funziona bene. Anche se introduco un ritardo di 30 secondi nella risposta del mio server web, JsonDownloader esiste ancora ed è correttamente richiamato.

Quindi le mie domande sono le seguenti: Che cosa impedisce a JsonDownloader di superare la fine del ciclo degli eventi? Lo sto esplicitamente rilasciando.

La mia impressione è che NSURLConnection deve fare un fermo sul suo delegato, ma non ho visto nulla nella documentazione. Qualcuno ha un'idea?

risposta

25

Non ci sono molti setter che non copiano o conservano una variabile passata ad esso, per evitare che la memoria di detta variabile venga riallocata a qualcos'altro quando il suo conteggio di ritenzione raggiunge lo zero.

Tuttavia, la risposta è Sì, lo fa. Un po 'di codice di test mostra mantenere conteggio del delegato salire:

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]); 

che produce nel registro:

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. 

Così si può vedere abbastanza chiaramente che nel connectionWithRequest:delegate: "sé" sta infatti avendo il suo mantenere il conteggio aumentato di +1. Se vi sentite coraggiosi e volete pasticciare con gli dei EXC_BAD_ACCESS, aggiungere

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

che stamperà fuori "1" di nuovo, mostrando un decremento posta dealloc. Tuttavia, si otterrà un bel Program received signal: “EXC_BAD_ACCESS”. perché il NSAutoreleasePool cercherà di rilasciare la connessione e sarà andato;)

+1

Ottima domanda e ottima risposta. Anch'io stavo lottando con questo, ma ho deciso di aggiungere [self release] subito dopo che il delegato ha assegnato il pareggio. Dal momento che il sé è delegato nella mia classe, non ho visto alcun motivo per aumentare il numero di ritenzione. Se ciò non è corretto, qualcuno me lo faccia sapere. – jocull

+0

Voglio solo aggiungere - grazie. Il Mancante Manuale, parte 327. E 'mendicante credenza che questo tipo di fatto importante non sia menzionato nella documentazione di Apple. Ho pensato che lo stesse conservando, ma non ero sicuro, i doc non ne hanno parlato, e in molti se non molti casi in cui i delegati in framework Cocoa sono * non * mantenuti. Questa è l'eccezione. – n13

9

maggior delegato proprietà non vengono mantenute, ma assegnati per evitare riferimenti circolari. Vedi anche la domanda this.

Tuttavia, NSUrlConnection non ha una proprietà delegato specifica. Devi specificare il delegato insieme all'inizializzazione della connessione. Penso che sia per questo che riceve una riserva, come ha mostrato Dave Martorana.