2009-09-30 9 views
5

Cela pourrait être le motif de conception que je ne connais pas.Obtention de Xcode pour supprimer l'avertissement "No XXX method found" lors de la délégation

J'implémente la délégation asynchrone dans une application qui utilise NSURLConnection. Un objet enveloppe le NSURLConnection et gère ses messages délégués; ça fonctionne bien. Maintenant, je définir mes propres délégués dans l'objet qui l'utilise (NSURLConnection messages ConnectionWrapper, ConnectionWrapper messages NeedsToUseConnection, vous voyez l'idée), et qui fonctionne aussi bien, cependant, Xcode émet cet avertissement:

Non ' -request: méthode finishedWithResult » trouvé

Ceci est, sans doute, parce que je déclare le délégué que je vous appelle comme ceci:

id<NSObject> delegate; 

... et Xcode est che cking ce que NSObject déclare dans le cadre de la Fondation. Mon message de délégué personnalisé n'est pas là. Je suis bien isolante l'appel:

if([delegate respondsToSelector:@selector(request:finishedWithResult:)]) 
    [delegate request:self finishedWithResult:ret]; 

En plus de tourner l'avertissement off - J'aime travailler avec autant de mises en garde sur que possible - est-il un moyen de communiquer (soit syntaxiquement ou via une directive du compilateur) que je suis conscient que ce message n'est pas déclaré? Dois-je, au contraire, utiliser un modèle de conception d'interface pour ce Java? En utilisant id<WillReceiveRequestMessages> ou quelque chose?

Ouvert à la suggestion.

Répondre

10

Une meilleure façon de le faire serait de créer votre propre protocole délégué:

@protocol MyControlDelegate <NSObject> 

@optional 
- (void)request:(MyControl *)request didFinishWithResult:(id)result; 

@end 

Ensuite, vous déclarer votre délégué comme ceci:

id <MyControlDelegate> delegate; 

Le compilateur ne se plaindra plus quand vous écrivez ceci:

if ([delegate respondsToSelector:@selector(request:didFinishWithResult:)]) 
    [delegate request:self didFinishWithResult:result]; 

La syntaxe <NSObject> est importa nt dans la définition de protocole car il indique au compilateur d'incorporer le protocole NSObject. C'est ainsi que votre protocole obtient des méthodes comme respondsToSelector:. Si vous l'avez laissé de côté, le compilateur commencerait à se plaindre de respondsToSelector: à la place.

+1

Merci. Je viens de voir un exemple de cela avec UIAlertViewDelegate, et c'est très utile. –

0

C'est, sans doute, parce que je déclare le délégué J'appelle comme ceci: ... et Xcode vérifie ce que NSObject déclare dans le cadre Fondation .

Ceci est incorrect. Si tel était le cas, vous obtiendriez un avertissement à propos de l'objet "peut ne pas répondre à" la méthode, ou quelque chose comme ça. C'est un problème complètement séparé.

Cet avertissement est dû au fait que le compilateur doit connaître la signature d'un sélecteur pour l'appeler. En effet, en coulisses, le compilateur convertit un appel de méthode vers objc_msgSend ou objc_msgSend_stret selon que la méthode renvoie un type struct ou non.S'il ne connaît pas le type de retour, il devinera qu'il ne s'agit pas d'un struct et utilisera la première fonction. Cependant, cela pourrait être faux.

La solution est de faire déclarer la méthode n'importe où. Il n'a même pas à être déclaré dans la bonne classe. Vous pouvez le déclarer dans un protocole fictif qui n'est jamais utilisé. Tant qu'il est déclaré quelque part, le compilateur le saura et sera capable de le compiler correctement.

Questions connexes