我正在尝试为一个应该调用它的委托(如果有的话)的类实现委托,当特殊情况发生时。
来自维基百科我有这个代码示例:
@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
如果我自己尝试这个,我会收到警告,说明找不到我在代理上调用的方法。当然不是,因为委托只是由id引用。它可能是任何东西。当然在运行时会工作正常,因为我检查它是否响应选择器。但我不想在Xcode中发出警告。有更好的模式吗?
答案 0 :(得分:7)
您可以让委托属于实现SomeClassDelegate协议的id类型。为此,您可以在SomeClass的标题中(在您的情况下为TCScrollView),执行以下操作:
@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
然后你可以从你的实现中,只需调用委托上的方法:
@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
答案 1 :(得分:0)
跟进drvdijk's answer中的示例代码,如果在调用委托方法时delegate
可能nil
,则可能会出现问题。
发送到nil
的邮件的返回值为nil
(又名0.0
又名0
又名NO
),因此如果delegate
是nil
,
[delegate scrollView:self shouldScrollToPoint:to]
将返回NO
,这可能不是您所希望的行为。首先检查更安全:
if (delegate != nil) {
shouldScroll = [delegate scrollView:self shouldScrollToPoint:to]
}
此外,如果您不希望在将NSObject
声明的消息发送给您的代理时发现编译器警告(例如respondsToSelector:
),请在协议中包含NSObject
协议声明:
@protocol TScrollViewDelegate <NSObject>
- (BOOL) scrollView:(TCScrollView *)tcScrollView shouldScrollToPoint:(CGPoint)to;
@end
答案 2 :(得分:0)
[delegate performSelector:@selector(scrollView:shouldScrollToPoint:) withObject:self withObject:to];
您将不再收到编译器警告。
或者创建prototcol并在头文件中声明MyProtocol *delegate
。