【问题标题】:iOS 5.0 Warning: Cannot find protocol definition for DelegateiOS 5.0 警告:找不到委托的协议定义
【发布时间】:2012-10-15 09:10:53
【问题描述】:

我有自定义 UIView 类 GestureView。我有这个类的前向声明,它是下面的代表。我在 .m 文件中导入了 GestureView.h。这工作正常,但 iOS 发出警告消息说“找不到 GestureViewDelegate 的协议定义”。如果我删除前向声明,它会给出与错误相同的警告消息。我不想从 ContainerViewController.h 导入 GestureView.h,因为我通常会在 .m 文件中导入东西。有人可以解释一下类结构有什么问题吗?

ContainerViewController.h

#import <UIKit/UIKit.h>

@class DividerView;
@class GestureView;
@protocol GestureViewDelegate;

@interface ContainerViewController : UIViewController<GestureViewDelegate>
   @property (strong, nonatomic) IBOutlet GestureView *topContentView;
@end

GestureView.h

#import <UIKit/UIKit.h>

@protocol GestureViewDelegate;

@interface GestureView : UIView
    - (void)initialiseGestures:(id)delegate;
@end

@protocol GestureViewDelegate <NSObject>
@required
- (void)GestureView:(GestureView*)view handleSignleTap:(UITapGestureRecognizer*)recognizer;
@end

【问题讨论】:

  • 你的协议是在哪里定义的?
  • 您可以在我发布的代码中看到!它在 GestureView.h 中!
  • ContainerViewController.h 尝试#import GestureView.h 而不是前向声明
  • 我提到我不想那样做!如果您知道前向声明有什么问题,请告诉我。谢谢。

标签: objective-c ios5 protocols forward-declaration


【解决方案1】:

我喜欢您尝试避免在头文件中导入:非常好的做法。但是,要修复您的错误,您可以使您的代码变得更好!在我看来,你的ContainerViewController 类没有必要对外声明它支持GestureViewDelegate 协议,所以你应该把它移到你的实现文件中。像这样:

GestureView.h

#import <UIKit/UIKit.h>


@protocol GestureViewDelegate;

@interface GestureView : UIView

- (void)initialiseGestures:(id <GestureViewDelegate>)delegate;

@end


@protocol GestureViewDelegate <NSObject>
@required

- (void)gestureView:(GestureView *)view handleSingleTap:(UITapGestureRecognizer *)recognizer;

@end

ContainerViewController.h

#import <UIKit/UIKit.h>


@class GestureView;

@interface CollectionViewController : UIViewController

// this property is declared as readonly because external classes don't need to modify the value (I guessed seen as it was an IBOutlet)
@property (strong, nonatomic, readonly) GestureView *topContentView;

@end

ContainerViewController.m

#import "ContainerViewController.h"
#import "GestureView.h"


// this private interface declares that GestureViewDelegate is supported
@interface CollectionViewController () <GestureViewDelegate>

// the view is redeclared in the implementation file as readwrite and IBOutlet
@property (strong, nonatomic) IBOutlet GestureView *topContentView;

@end


@implementation ContainerViewController

// your implementation code goes here

@end

【讨论】:

  • 太棒了尼尔!我理解你的解决方案,它对我来说完全有意义,但我想知道 UITableView-Delegate 和 Datasource 等其他协议是如何实现的?您可以在头文件声明本身中实现它们!无论如何我们不能创建我们的自定义协议,这样当你实现它时,你必须覆盖@required 方法?如果我们不实现它们,那么根本就没有协议。我可以简单地从 ContainerViewController 中完全删除协议委托变量,然后在 initialiseGestures 中传递它的 id。
  • 此外,在这种情况下,iOS 编译器根本不应该给出警告信息。前向声明旨在避免编译时警告和错误!不是吗?
  • 虽然这可行,但更清楚的是,将受支持的委托列在一个地方 - 列出所有标准委托的头文件。例如,在我的.h 文件中,我可能有&lt;UITableViewDelegate, UITableViewDataSource&gt;,理想情况下我想把所有代表都放在那里。这是怎么做到的?
  • @TRedman 在这种情况下,我的建议是在单独的头文件(例如GestureViewDelegate.h)中声明GestureViewDelegate,它可以在实现头文件中导入(而类本身可以是前向声明)。
  • 谢谢 Ell,今天早上我就是这么想的。
【解决方案2】:

试试这个方法,行不通请回复。

GestureView.h

#import <UIKit/UIKit.h>

@protocol GestureViewDelegate <NSObject>
@required
- (void)GestureView:(GestureView*)view handleSignleTap:(UITapGestureRecognizer*)recognizer;
@end

@interface GestureView : UIView
    - (void)initialiseGestures:(id)delegate;
@end

ContainerView.h

#import <UIKit/UIKit.h>

@class DividerView;
@class GestureView;
/*@protocol GestureViewDelegate;*/ //NO NEED TO WRITE THIS

@interface ContainerViewController : UIViewController<GestureViewDelegate>
   @property (strong, nonatomic) IBOutlet GestureView *topContentView;
@end

【讨论】:

  • 不,它不起作用。我已经试过了。它给出与 ERROR 相同的警告信息!
猜你喜欢
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多