2010-04-27 4 views
2

J'ai implémenté le modèle de rappel délégué entre deux classes sans conserver le délégué. Mais dans certains cas, le délégué est libéré.gérer lors du rappel à un délégué désalloué?

(Mon cas est que j'ai un ViewController est l'objet délégué, et lorsque le bouton de retour presse utilisateur pop qui ViewController de la pile NavigationController)

Ensuite, la méthode de rappel se BAD_EXE:

if (self.delegate != nil && [self.delegate respondsToSelector:selector]) { 
    [self.delegate performSelector:selector withObject:self withObject:returnObject]; 
} 

Je sais que le modèle de rappel délégué est implémenté dans beaucoup d'applications. Quelle est votre solution pour cela?

+0

Quelqu'un a dit que nous ne pouvons pas tester une instance d'objet dealloced: http://stackoverflow.com/questions/983333/objective-c-test-for-object-instance-being-dealloced-freed – KONG

Répondre

2

Généralement, un délégué doit toujours le désassocier de son objet délégué dans sa méthode dealloc. Votre contrôleur de vue doit donc vérifier dans son dealloc s'il est défini en tant que délégué de la classe délégante et, le cas échéant, définir la propriété de délégué sur nil.

Dans la plupart des cas, j'imagine que ce ne serait pas un problème car très souvent le délégué est le seul propriétaire de l'objet délégué. Ainsi, lorsque le délégué est libéré, l'objet délégué est également désaffecté. Après tout, c'est la raison pour laquelle les objets délégués ne contiennent généralement que de faibles références à leurs délégués.

+0

J'essaie suivre la façon dont NSURLConnection implémente le délégué - callback. En utilisant ceci, je n'ai pas besoin de conserver l'objet délégué. ClassA: Initalize NetworkClass, appelez-le pour effectuer une tâche NetworkClass * networkObject = [[NetworkClass alloc] init]; [networkObject getSomethingWithDelegate: self]; Lorsque callbacking, NetworkClass passe elle-même pour libérer dans ClassA - (void) networkClass: (NetworkClass *) networkObject didGetSomething: (NSObject *) returnObject {// faire avec returnObject [communiqué networkObject]; networkObject = nil; } Mais je devrais changer cela pour faire comme vous l'avez dit. – KONG

+0

J'essaie de libérer l'objet délégué lors de la libération de l'objet délégué. Toutefois, dans certaines bibliothèques, par exemple, comme MGTwitterEngine, NSURLConnection, l'objet délégué se conserve et je ne peux pas libérer l'objet délégué. Avez-vous une idée? – KONG

+0

J'ai dit que vous devriez mettre la propriété delegate à zéro (dans certaines circonstances), pas que vous deviez publier quoi que ce soit. Vous ne devez JAMAIS libérer un objet que vous ne possédez pas. Honnêtement, je ne comprends pas votre question. –

0

Je n'ai aucune connaissance c objectif, mais je pense que vous devez tester séparément self.delegate != nil par exemple

if (self.delegate != nil) 
{ 
if ([self.delegate respondsToSelector:selector]) 
{ 
    [self.delegate performSelector:selector withObject:self withObject:returnObject]; 
} 
} 

Oh, et il est préférable de réassigner le délégué si elle est nulle.

+0

Non, cela ne va pas aider. La propriété 'delegate' pointera toujours vers une adresse mémoire mais l'objet qui était à cette adresse est désalloué. Il n'y aurait pas de problème si le délégué était «nul». –

+0

Okay. Je me demandais juste comme j'ai déjà rencontré le problème où le test d'une valeur "nulle" ou "nulle" ainsi que le fait de vérifier qu'il peut avoir une autre valeur posent des problèmes. D'après ce que vous dites, je suppose que ce n'est pas un problème avec l'objectif-c. J'ai compris que le PO avait dit que le délégué avait été libéré, mais maintenant je vois que ce n'est pas toujours le cas. – ChrisBD

+0

Si la première instruction d'une vérification && échoue, la seconde ne sera pas évaluée. – quantumpotato

Questions connexes