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

时间:2012-05-17 16:43:01

标签: objective-c ios delegates protocols

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

//.h
#import <UIKit/UIKit.h>
//@interface ViewController : UIViewController <UIAlertViewDelegate> 
@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

4 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:6)

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

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

@interface MyClass : NSObject <delegateProtocolName>  

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

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

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

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

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

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

引用conformsToProtocol的文档(取自The Objective-C Programming Language并由我添加的重点):

  

此方法仅在正式的基础上确定一致性   头文件中的声明,如上所示。它没有检查   查看协议中声明的方法是否实际   实施 - 这是程序员的责任。

答案 2 :(得分:3)

答案是苹果不想要一个类来实现UIAlertViewDelegate协议。如果Apple希望要求,那么它将使UIAlertView的委托属性为id<UIAlertViewDelegate>。如果你查看文档,那就不是。

UIAlertView Class Reference

  

@property(nonatomic, assign) id delegate

他们必须有理由不做@property(nonatomic, assign) id<UIAlertViewDelegate> delegate

答案 3 :(得分:1)

您在班级中提到的&lt; UIAlertViewDelegate&gt; 意味着您正在此类中实现AlertView委托的方法,即ViewController 委托:self 表示此对象的委托方法在当前类中定义。

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

并且您还必须更改委托:( classname)。