Objective C protocol as an equal to Java Interface?

不羁岁月 提交于 2019-12-21 05:18:10

问题


The question is not only regarding the headline, but more of a "how will I achieve this, without trying to force a Java/Flash design into an Objective C (iPhone)program".

I have 6 views that extends UIView, these views all have different behavior but share certain methods, like -(void) update and -(void) changeState:(NSInteger)state.

A viewController, whose job is it to update, instantiate and display these views has a switch block to do this. So switch(4) {...} instantiates UIView4, but as I need a reference to the currently instantiated view (to do update and changeState:), I have a UIView property on my ViewController called self.currentView. As the instantiated UIView4 extends UIView I can easily go [self.currentView addSubview:UIView4instance] and then release the UIView4instance.

Now how will I call the [UIView4instance update] method on the view? or the [UIView5instance changeState] etc. etc. Since I added it to self.currentView which is of type UIView it no longer has any reason to believe it has an update or changeState: method, meaning I cannot iterate the views and send them these messages.

This approach brings on a ton of other problems, I would need to test and typeCast my views each time I needed to do any operations on them.

If I were doing something like this Composite Pattern approach in, say, Java. I would either write an interface that all the views (UIView1, UIview2.... UIViewN) would implement. Or maybe an abstract class that all the views inherited the changeState: and update methods from.

This way I could have self.currentView just know that I'm adding objects to your view and they all conform to these methods.

The two solutions I can think of, with my very small Objective-C experience is: doing it with delegation or categories, but this seems overkill in every way :/ I guess I could also extend UIView and then extend my class extending UIView again, but there is probably a reason Objective-C does not directly support abstract classes...

Hope someone could point me in the right direction regarding these issues. Thanks:)


回答1:


Yes it is equal. You can declare a protocol

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

and declare your subclasses like

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

Then, the declaration

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

means that view is an instance (of a subclass of) UIView which also conforms to MyViewProtocol. Just the way it works in Java, I think. See the apple doc on protocols.




回答2:


One thing to be aware of is that while defining a protocol like this is a convenience and certainly makes things clearer, it is by no means necessary to make your solution work. Objective-C binds methods at runtime, and so all you really need to do is to make sure all your view classes implement the methods you care about and call them.

You will get a complier warning for this, but it will work.

Now, in general it's probably preferable to define a protocol like this and it's what I generally do. But it's also important to remember that runtime binding is there and can be incredibly powerful.



来源:https://stackoverflow.com/questions/2001456/objective-c-protocol-as-an-equal-to-java-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!