Wie kann ich die Delegation richtig implementieren?
-
11-07-2019 - |
Frage
Ich versuche, die Delegation für eine Klasse implementieren zu können, die sie als Delegate bezeichnen sollte (falls vorhanden), wenn besondere Dinge passieren.
Aus Wikipedia habe ich dieses Code -Beispiel:
@implementation TCScrollView
-(void)scrollToPoint:(NSPoint)to;
{
BOOL shouldScroll = YES;
// If we have a delegate, and that delegate indeed does implement our delegate method,
if(delegate && [delegate respondsToSelector:@selector(scrollView:shouldScrollToPoint:)])
shouldScroll = [delegate scrollView:self shouldScrollToPoint:to]; // ask it if it's okay to scroll to this point.
if(!shouldScroll) return; // If not, ignore the scroll request.
/// Scrolling code omitted.
}
@end
Wenn ich das alleine versuche, bekomme ich eine Warnung, dass die Methode, die ich den Delegierten aufrufe, nicht gefunden wurde. Natürlich war es nicht, weil der Delegierte nur durch ID verwiesen wird. Es könnte alles sein. Sicher, zur Laufzeit, die gut funktioniert, da ich überprüfe, ob es auf Selektor reagiert. Aber ich will die Warnung in Xcode nicht. Gibt es bessere Muster?
Lösung
Sie könnten den Delegierten vom ID -Typ sein, der das SomeclassDelegate -Protokoll implementiert. Dazu könnten Sie im Kopf Ihrer Someklasse (in Ihrem Fall tcScrollView) so etwas tun:
@protocol TCScrollViewDelegate; // forward declaration of the protocol
@interface TCScrollView {
// ...
id <TCScrollViewDelegate> delegate;
}
@property (assign) id<TCScrollViewDelegate> delegate;
@end
@protocol TCScrollViewDelegate
- (BOOL) scrollView:(TCScrollView *)tcScrollView shouldScrollToPoint:(CGPoint)to;
@end
Anschließend können Sie aus Ihrer Implementierung die Methode im Delegierten anrufen:
@implementation TCScrollView
-(void)scrollToPoint:(NSPoint)to;
{
BOOL shouldScroll = YES;
shouldScroll = [delegate scrollView:self shouldScrollToPoint:to]; // ask it if it's okay to scroll to this point.
if(!shouldScroll) return; // If not, ignore the scroll request.
/// Scrolling code omitted.
}
@end
Andere Tipps
Nachfolger des Beispielcode in DRVDIJKs Antwort, Es könnte ein Problem geben, wenn es eine Chance gibt delegate
könnte sein nil
Wenn Sie die Delegate -Methode aufrufen.
Der Rückgabewert einer Nachricht, die an gesendet wird nil
ist nil
(AKA 0.0
AKA 0
AKA NO
), also wenn delegate
ist nil
,
[delegate scrollView:self shouldScrollToPoint:to]
wird zurückkehren NO
, was in Ihrem Fall möglicherweise nicht das gewünschte Verhalten ist. Es ist sicherer, zuerst zu überprüfen:
if (delegate != nil) {
shouldScroll = [delegate scrollView:self shouldScrollToPoint:to]
}
Auch wenn Sie keine Compiler -Warnung sehen möchten NSObject
zu Ihrem Delegierten (wie z. respondsToSelector:
), umfassen die NSObject
Protokoll in Ihrer Protokolldeklaration:
@protocol TScrollViewDelegate <NSObject>
- (BOOL) scrollView:(TCScrollView *)tcScrollView shouldScrollToPoint:(CGPoint)to;
@end
Verwenden [NSObject performSelector:]
[delegate performSelector:@selector(scrollView:shouldScrollToPoint:) withObject:self withObject:to];
Sie werden die Compiler -Warnungen nicht mehr bekommen.
Alternativ ein Prototcol erstellen und deklarieren MyProtocol *delegate
in der Header -Datei.