10

每当我创建一个具有符合协议的委托的 init 时,我将 init 编写为:

- (id)initWithDelegate:(id<ProtocolToConform>)delegate;

这样,如果创建对象不符合协议,我将收到警告。

但是我注意到 ie UIAlertViewinit 方法看起来像这样:

- (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...

委托参数没有指定符合UIAlertViewDelegate协议?任何线索为什么Apple会这样做?

4

2 回答 2

4

好问题!我做同样的事情是希望在编译时发现更多错误。

苹果似乎符合自己的标准;如Objective-C 中的概念中所述:

要为您的自定义类实现委托,请完成以下步骤:

在类头文件中声明委托访问器方法。

- (id)delegate;
- (void)setDelegate:(id)newDelegate;

实现访问器方法。在内存管理的程序中,为避免保留循环,setter 方法不应保留或复制您的委托。

- (id)delegate {
    return delegate;
}
 
- (void)setDelegate:(id)newDelegate {
    delegate = newDelegate;
}
于 2013-01-31T13:22:00.330 回答
2

我的理解是几年前 API 是一团糟,他们仍在修复所有这些问题。

请注意,直到最近,许多协议都是非正式的,并且几乎在 API 中的任何地方,您都只能在id. Apple 在每个版本中逐步修复它,例如NSURLConnectioniOS 6.0 附带的正式代表。或者请注意,在 iOS 6.1 中,一些id返回类型已更改为instancetype.

嗯,这是我最初的想法,在检查了头文件之后:

@property(nonatomic,assign) id /*<UIAlertViewDelegate>*/ delegate

很明显有人想将协议添加到声明中,但只添加了注释。我猜他们在没有协议的情况下留下了兼容性。

于 2013-01-31T13:42:52.930 回答