【问题标题】:Syntax for resolving incompatible property type on inherited delegate解析继承委托上不兼容的属性类型的语法
【发布时间】:2011-11-18 20:27:54
【问题描述】:

我继承的一些代码有一个烦人的警告。它声明一个协议,然后使用它来指定委托

@protocol MyTextFieldDelegate;

@interface MyTextField: UITextField
@property (nonatomic, assign) id<MyTextFieldDelegate> delegate;
@end

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
- (void)myTextFieldSomethingHappened:(MyTextField *)textField;
@end

使用myTextField 的类实现MyTextFieldDelegate 并使用以下代码调用它:

if ([delegate respondsToSelector:@selector(myTextFieldSomethingHappened:)])
{
    [delegate myTextFieldSomethingHappened:self];
}

这可行,但会产生(合法的)警告:警告:属性类型“id”与继承自“UITextField”的类型“id”不兼容

以下是我想出的解决方案:

  1. 删除该属性。这可行,但我收到警告 '-myTextFieldSomethingHappened:' not found in protocol(s)
  2. 完全放弃协议。没有警告,但如果您忘记在委托中实现协议,也会丢失语义警告。

有没有办法定义委托属性以使编译器满意?

【问题讨论】:

    标签: objective-c ios delegates protocols


    【解决方案1】:

    尝试:

    @property (nonatomic, assign) id<UITextFieldDelegate,MyTextFieldDelegate> delegate;
    

    【讨论】:

    • 非常棒,而且很有道理。
    • 我终于(在提出这个问题两年后,在得到明确答案后一年)开始在我的代码中解决这个问题。我只是想说“请注意并感谢”。
    【解决方案2】:

    UITextField 也有名为delegate 的属性,但它有另一种类型。只需将您的 delegate 属性重命名为其他名称即可。

    【讨论】:

    • 这会比使用委托和避开语法检查带来更多风险。
    • 我完全不明白你的意思是什么风险。
    • 有两个字段作为代理存在维护风险;有人使用代码并引用错误的委托字段太容易了。
    • 这就是我告诉你重命名它的原因。类有多个委托是绝对正常的(例如 UITableView 有委托和数据源属性)。
    • 你是对的,通常有多个代表,特别是当服务不同的目的时;这是一个传统的回调“委托”,我不想添加委托 2、扩展委托或任何其他几乎委托的名称。我最终使用了从委托中删除协议,依赖于 [xyzzy respondsTo:] 测试。我一直希望有一种语法可以将我的规范传达给编译器。由于您的答复是唯一的答复,因此如果您可以对其进行编辑以指示我的问题没有已知的语法,我将接受它作为解决方案。谢谢。
    【解决方案3】:

    在 UITableView.h 中找到了答案。

    UIScrollView 有属性名delegate,UITableView 有同名属性。

    @protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
    // Your code
    ......
    
    @end
    

    【讨论】:

      【解决方案4】:

      原来的问题是在delegate属性的声明过程中没有关于MyTextFieldDelegate的继承信息。它是由协议的前向声明(@protocol MyTextFieldDelegate;)引起的。

      我遇到了同样的问题,但在另一个 .h 文件中声明了协议。在我的情况下,解决方案只是#import 适当的标题。

      在你的情况下,你只需要交换声明的顺序:

      @class MyTextField;
      
      @protocol MyTextFieldDelegate <UITextFieldDelegate>
      @optional
      - (void)myTextFieldSomethingHappened:(MyTextField *)textField;
      @end
      
      @interface MyTextField : UITextField
      @property (nonatomic, assign) id <MyTextFieldDelegate> delegate;
      @end
      

      【讨论】:

      • 我还需要在实现中添加@dynamic 以消除警告
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2012-05-08
      • 2023-03-03
      • 2018-05-29
      相关资源
      最近更新 更多