1

当发生特殊事情时,我正在尝试为一个应该称之为委托(如果有的话)的类实现委托。

从维基百科我有这个代码示例:

 @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 中的警告。有更好的模式吗?

4

3 回答 3

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
于 2009-08-03T16:33:02.870 回答
0

跟进drvdijk 答案中的示例代码,如果在调用委托方法时有任何机会,则可能会出现问题delegatenil

发送到的消息的返回值为nil( nilaka 0.0aka 0aka NO),所以如果delegatenil,

[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
于 2009-10-27T17:23:58.513 回答
0

采用[NSObject performSelector:]

[delegate performSelector:@selector(scrollView:shouldScrollToPoint:) withObject:self withObject:to];

您将不会再收到编译器警告。

或者创建一个协议并MyProtocol *delegate在头文件中声明。

于 2009-10-27T17:31:19.353 回答