2010-09-12 2 views
57
- (void)someMethod 
{ 
    if ([delegate respondsToSelector:@selector(operationShouldProceed)]) 
    { 
     if ([delegate operationShouldProceed]) 
     { 
      // do something appropriate 
     } 
    } 
} 

Die documentation sagt verwenden:wenn respondsToSelector in Objective-c

Die Vorsichtsmaßnahme notwendig ist, nur für optionale Methoden in einem formellen Protokoll oder Methoden eines informellen Protokoll

Was tut es bedeutet? Wenn ich ein formelles Protokoll verwende, kann ich einfach [delegate myMethod] verwenden?

Antwort

74

Sie verwenden es ziemlich genau dann, wenn Sie denken, Sie müssen: um zu überprüfen, ob ein Objekt die Methode implementiert, die Sie anrufen werden. Normalerweise Dies ist getan, wenn Sie eine optionale Methoden oder ein informelles Protokoll haben.

Ich habe nur respondsToSelector verwendet, wenn ich Code schreibe, der mit einem Delegatobjekt kommunizieren muss.

if ([self.delegate respondsToSelector:@selector(engineDidStartRunning:)]) { 
     [self.delegate engineDidStartRunning:self]; 
    } 

Sie manchmal möchte respondsToSelector auf jeder Methode verwenden, und id oder generische NSObject zurück, wo Sie nicht sicher sind, was die Klasse des zurückgegebenen Objekts ist.

+0

danke. Ich verstehe jetzt.Ich habe bemerkt, dass Sie self.delegate verwenden, was eine Eigenschaft ist. Ich benutze nur eine Instanzvariable: ID Delegate. was ist der Unterschied? Im Lernziel-c. danke nochmal – Taho

+2

'self.delegate' ist genau das Selbe wie' 'self delegate'' zu nennen. In meinem Code gibt es keinen Unterschied zwischen '[self.delegate someMethod]' und '[_delegate someMethod]', aber ich neige dazu, die Punktsyntax zu verwenden, weil ich genau weiß, welche Variablen lokal für die Methode sind das sind Instanzvariablen. – kubi

+0

Wenn Sie gerade erst anfangen, wird es sich lohnen, Apple's Guide zu Obj-C zu lesen. http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html%23//apple_ref/doc/uid/TP30001163-CH17 – kubi

45

Nur um hinzuzufügen, was @kubi sagte, ein anderes Mal verwende ich es, wenn eine Methode zu einer bereits vorhandenen Klasse in einer neueren Version der Frameworks hinzugefügt wurde, aber ich muss immer noch abwärtskompatibel sein. Zum Beispiel: @selector (fu :) weil der Methodenname überprüft wird nicht noch in Refactoring von XCODE enthalten:

if ([myObject respondsToSelector:@selector(doAwesomeNewThing)]) { 
    [myObject doAwesomeNewThing]; 
} else { 
    [self doOldWorkaroundHackWithObject:myObject]; 
} 
2

alter Frage, aber ich habe sehr cautios mit der Verwendung von Sachen wie addTarget sein gelernt. Das hat mir schon einige Probleme bereitet. So jetzt habe ich es ein habbit gemacht, immer einbetten Sachen wie addTarget oder addObserver in einem respondsToSelector-Check etwa so:

if([self respondsToSelector:@selector(buttonClicked:)]){ 
    [self.button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 
}else{ 
    DebugLog(@"Warning - a class or delegate did not respond to selector in class %@", self); 
} 

Ich weiß, seine nicht super elegant, aber ich würde eher etwas vorformulierten Code hinzuzufügen, als eine unerwartete haben Absturz meiner Apps im App Store.

+0

Ich denke, "methodName:" ist nun eingecheckt in Anweisungen wie @selector (methodName :) in xCode jetzt nicht wahr? – Grezzo

+1

@Grezzo - XCode überprüft nur, ob der Selektor irgendwo in Ihrem Ziel existiert. Wenn Sie zum Beispiel '@selector (date)' anstelle von '@selector (data)' 'geschrieben haben, wird XCode Sie nicht warnen, da der' date' Selektor auf 'NSDateComponents' existiert. – Robert

11

Als Kubi erwähnt respondsToSelector wird normalerweise verwendet, wenn Sie eine Instanz einer Methode haben, die einem Protokoll entspricht.

// Extend from the NSObject protocol so it is safe to call `respondsToSelector` 
@protocol MyProtocol <NSObject> 

// @required by default 
- (void) requiredMethod; 

@optional 

- (void)optionalMethod; 

@end 

Gegeben und Instanz dieses Protokolls können wir sicher jede erforderliche Methode aufrufen.

id <MyProtocol> myObject = ... 
[myObject requiredMethod]; 

Allerdings können optionale Methoden implementiert werden oder nicht, so dass Sie zur Laufzeit überprüfen müssen.

if ([myObject respondsToSelector:@selector(optionalMethod)]) 
{ 
    [myObject optionalMethod]; 
} 

Dadurch wird ein Absturz mit einem nicht erkannten Selektor verhindert.


Auch der Grund, warum Sie Protokolle als Erweiterung von NSObjects, das heißt

@protocol MyProtocol <NSObject> 

ist, weil das NSObject Protokoll erklärt die respondsToSelector: Wähler zu erklären. Andernfalls würde XCode denken, dass es unsicher ist, es anzurufen.

+0

Ich habe gerade vergessen hinzuzufügen löste mein Problem danke –

Verwandte Themen