2010-03-23 6 views
2

Si vous créez un NSURLConnection et que vous appelez [connectionWithRequest], laissez le charger un peu puis appelez [connection cancel] la plupart du temps. Cependant parfois même après que j'appelle [connexion cancel] le délégué de la connexion est toujours appelé (ce qui bloque l'application). Googler autour il semble que le problème ici est une condition de course dans le runloop, j'annule la connexion et libère le délégué, mais avant les cycles de cycle de roulement, il appelle les fonctions de délégué -> crash.NSURLConnection appelle toujours le délégué AFTER Annuler la méthode a été appelée

Y a-t-il un moyen pour moi, après avoir appelé [Annulation de la connexion] confirmer que la connexion a effectivement été annulée? Même une boucle while merdique() fera :(

+0

Même problème ici. Notez que dans la grande majorité des cas, 'cancel' fonctionne correctement, et ni connectionDidFinishLoading' ni' connectionDidFailWithError' ne sont appelés sur le délégué. On dirait que rien de moins que l'extension juste-dans-cas sur la durée de vie de l'objet délégué peut résoudre ce problème. –

Répondre

6

Vous ne devriez pas libérer la connexion & stockage associé jusqu'à ce que votre délégué reçoit soit un connectionDidFinishLoading: ou Toutefois, dans ce cas, un message connectionDidFailWithError:.

Delegates are not normally retained by the object they're acting as delegate for. Il est donc le délégué ne doit pas devenir invalide pendant que le NSURLConnection s'y réfère toujours, sauf si vous le libérez d'une manière ou d'une autre

+0

C'est une bonne règle, je vais essayer de l'implémenter. – Shizam

+0

@David Gelhar - Dans ce cas, il est conservé, mais les délégués ne sont ** PAS ** normalement conservés. D'après les documents d'Apple «Les objets délégués ne conservent pas (et ne devraient pas) leurs délégués, mais les clients qui délèguent des objets (applications, en général) sont chargés de veiller à ce que leurs délégués reçoivent les messages de délégation. Conserver le délégué dans le code géré par mémoire. " http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html#//apple_ref/doc/uid/TP40002974-CH7-SW18 – DougW

+1

Sauf les docs Apple disent que le délégué ne sera plus appelé après l'annulation, donc dans le cas normal, vous n'obtiendrez jamais connectionDidFinishLoading ou connectionDidFailWithError. – user1055568

0

Je n'ai pas encore rencontré ce problème, mais cela pourrait aussi fonctionner sans attacher votre objet délégué:

Étant donné que toutes les méthodes déléguées reçoivent l'objet Connexion appelant en tant que paramètre et que vous connaissez également votre objet Connexion actif (ou nil), ignorez simplement les actions de délégation en comparant les deux objets. De cette façon, un objet Connection "ghost" annulé peut toujours appeler le délégué mais ne pas interférer avec ses internes.

- (void) connection:(NSURLConnection*) connection didReceiveData:(NSData*) data 
{ 
    if(connection != _URLConnection){return;} 
    ... 
    [_incomingData appendData:data]; 
    ... 
} 

_URLConnection est une propriété dans votre délégué réglé sur une connexion active, ou nulle.

Questions connexes