【问题标题】:Objective C protocol as an equal to Java Interface?目标 C 协议等同于 Java 接口?
【发布时间】:2010-01-04 19:02:47
【问题描述】:

这个问题不仅与标题有关,而且更多的是“我将如何实现这一目标,而不试图将 Java/Flash 设计强制转换为 Objective C (iPhone) 程序”。

我有 6 个扩展 UIView 的视图,这些视图都有不同的行为但共享某些方法,例如 -(void) update-(void) changeState:(NSInteger)state

一个视图控制器,它的工作是更新、实例化和显示这些视图,它有一个开关块来执行此操作。所以 switch(4) {...} 实例化 UIView4,但由于我需要对当前实例化视图的引用(要执行 updatechangeState:),所以我的 ViewController 上有一个 UIView 属性,称为 self.currentView。由于实例化的 UIView4 扩展了 UIView,我可以轻松转到[self.currentView addSubview:UIView4instance],然后释放 UIView4 实例。

现在我将如何在视图上调用[UIView4instance update] 方法?或[UIView5instance changeState] 等等等等。 由于我将它添加到 UIView 类型的 self.currentView,它不再有任何理由相信它具有 updatechangeState: 方法,这意味着我无法迭代视图并向它们发送这些消息。

这种方法会带来很多其他问题,每次我需要对视图进行任何操作时,我都需要对其进行测试和类型转换。

如果我在 Java 中使用这种复合模式方法。我要么编写一个所有视图(UIView1,UIview2 .... UIViewN)都将实现的接口。或者可能是一个抽象类,所有视图都继承了 changeState:update 方法。

这样我就可以让self.currentView 知道我正在将对象添加到您的视图中,并且它们都符合这些方法。

根据我的 Objective-C 经验,我能想到的两个解决方案是: 用委托或类别来做,但这似乎在各个方面都过分了:/ 我想我也可以扩展 UIView,然后再次扩展我的类扩展 UIView,但可能是 Objective-C 不直接支持抽象类的原因......

希望有人能在这些问题上为我指明正确的方向。 谢谢:)

【问题讨论】:

    标签: objective-c inheritance interface


    【解决方案1】:

    是的,它是平等的。你可以声明一个协议

    @protocol MyViewProtocol
    -(void)update;
    -(void)changeState:(NSInteger)state;
    @end
    

    并声明你的子类

    @interface MyUIView3 : UIView<MyViewProtocol> {
    ....
    }
    ....
    @end
    

    然后,声明

    UIView<MyViewProtocol>* view=[[MyUIView3 alloc] init];
    

    表示viewUIView 的一个(子类)实例,它也符合MyViewProtocol。 就像它在 Java 中的工作方式一样,我想。见the apple doc on protocols

    【讨论】:

    • 您好,谢谢!太好了,就像我已经多次使用委托一样,我只是无法将这种方法“翻译”成您在此处提供的简单解决方案。我马上试试!
    【解决方案2】:

    需要注意的一点是,虽然定义这样的协议很方便,而且肯定会使事情变得更清晰,但这绝不是必要让您的解决方案工作。 Objective-C 在运行时绑定方法,因此您真正需要做的就是确保所有视图类都实现您关心的方法并调用它们。

    你会收到一个编译器警告,但它工作。

    现在,一般而言,定义这样的协议可能更可取,这也是我通常所做的。但同样重要的是要记住,运行时绑定是存在的,并且可以非常强大。

    【讨论】:

    • 嗨,保罗,感谢您的意见。我确实收到了运行时错误,因为我将 self.currentView 转换为 UIView。所以你说我可以将我的 currentView 转换为 id 然后以任何方式发送消息?
    • 您不必将其转换为任何内容。您可以随时向任何对象发送任何消息。您可能会收到编译器警告,但如果该类实现该方法,它将起作用。如果没有,你会得到一个错误,除非你也实现了 -forwardInvocation。您应该阅读 NSObject 文档中的相关文档,它很有启发性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 2011-01-28
    相关资源
    最近更新 更多