如何以正确的方式实施授权?

时间:2009-08-03 16:04:22

标签: iphone delegation

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

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

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

3 个答案:

答案 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),因此如果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

答案 2 :(得分:0)

使用[NSObject performSelector:]

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

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

或者创建prototcol并在头文件中声明MyProtocol *delegate