为什么我不需要在标题中声明UIAlertViewDelegate?

我认为我终于设法理解了委托的概念,直到发生以下情况:我更改了我的头文件以删除对委托的引用,并且警报仍然有效。 唯一的区别是我丢失了代码提示。

//.h #import  //@interface ViewController : UIViewController  @interface ViewController : UIViewController - (IBAction)showMessage:(id)sender; @end //.m #import "ViewController.h" @implementation ViewController - (IBAction)showMessage:(id)sender { UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Hello World!" message:@"Message." delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Button 1", @"Button 2", nil]; [message show]; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { NSString *title = [alertView buttonTitleAtIndex:buttonIndex]; if([title isEqualToString:@"Button 1"]) { NSLog(@"Button 1 was selected."); } } @end 

标头中的只是向编译器表明您打算在类中实现委托方法。 如果你没有实现标记为@required的委托方法,你会得到警告,但由于大多数委托方法通常是@optional,你的代码将编译并运行正常。 这并不意味着您不应该在标题中添加委托。

虽然你已经接受了答案,但这个问题还有很多问题。

UIAlertViewDelegate是一种实现委托设计模式协议 。 您可能需要或可能不需要通过采用它来正式通知运行时您符合任何给定协议(特别是如果它没有任何所需方法),但这取决于声明协议的类的设计。 您在类中采用协议,在声明类时将协议名称放在<>中,如下所示:

 @interface MyClass : NSObject  

由于委派的许多协议方法都是可选方法,因此它们通常会测试以查看采用类是否实现了这样的特定方法:

 if ([self.delegate respondsToSelector:@selector(delegatedMethod:)]) { // Do something } 

在这种情况下,您不需要符合头文件中的协议,因为它正在测试是否已实现特定的委托方法。

但是,测试可能会像这样编写(特别是如果你需要在同一个函数中引用多个必需的方法/属性):

 if ([self.delegate conformsToProtocol:@protocol(delegateProtocolName)]) { // Do something } 

在这种情况下,您必须符合头文件中的协议,否则它将无法通过测试。

引用conformsToProtocol的文档(取自Objective-C编程语言和我添加的重点):

此方法仅基于头文件中的正式声明来确定一致性 ,如上所示。 它不会检查协议中声明的方法是否实际实现 – 这是程序员的责任。

答案是苹果不想要一个类来实现UIAlertViewDelegate协议。 如果Apple希望这样做,它将使UIAlertView的委托属性类型为id 。 如果你看文档,它不是。

UIAlertView类参考

@property(nonatomic, assign) id delegate

他们必须有理由不使它成为@property(nonatomic, assign) id delegate

您在类中提到的意味着您正在此类中实现AlertView委托的方法,即ViewControllerdelegate:self表示此对象的委托方法在当前类中定义。

如果要在任何其他类中定义AlertView委托的方法,则必须在该类中提及并在该特定类中实现方法。

而且你必须改变委托:( classname)。