4

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

//.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

4 回答 4

9

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

于 2012-05-17T16:49:46.090 回答
6

虽然您已经接受了答案,但这个问题比那里解决的要多。

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

@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和我添加的重点):

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

于 2012-05-17T17:33:54.427 回答
3

答案是苹果不想要求一个类来实现 UIAlertViewDelegate 协议。如果 Apple 希望要求这样做,它会将 UIAlertView 的委托属性设置为 type id<UIAlertViewDelegate>。如果您查看文档,则不是。

UIAlertView 类参考

@property(nonatomic, assign) id delegate

他们一定有他们不成功的理由@property(nonatomic, assign) id<UIAlertViewDelegate> delegate

于 2012-05-17T17:03:11.823 回答
1

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

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

而且您还必须更改委托:(类名)。

于 2012-05-18T06:57:01.523 回答