我想允许不同观点之间的沟通。
我有两个较小的视图位于较大的视图之上,类似于iOS的视频播放器,但存在一些差异。当我点击较大的视图时,我想要切换视图外观,隐藏或取消隐藏。我有一个所有视图都符合的协议。我想将视图添加到另一个我称之为HideViewsService
的类中,该类具有NSArray
属性。我是否可以强制使用此HideViewsService
类的类,并添加视图,以仅添加符合此协议的视图?或者甚至只是UIViews
?
另外,我想在我知道所有的视图上调用一个方法,但我不知道如何通过编译器获取。这是我的-hideAllViews
方法:
-(void)hideAllViews
{
for(int i=0; i<self.viewArray.count; i++)
{
id obj = [self.viewArray objectAtIndex:i];
if([obj isKindOfClass:[UIView class]] == false)
{
return;
}
UIView *view = (UIView *)obj;
if([view respondsToSelector:@selector(hide)])
{
[view hide]; // the compiler obviously doesn't like this
}
}
}
谢谢!我还在学习,所以请告诉我是否有更好的方法(不仅更容易,而且更好)。
答案 0 :(得分:5)
ObjC没有泛型。如果有的话,有时会很好,但事实并非如此。但上述设计存在一些问题。
首先,如果viewArray
应该只包含UIView
个对象,那么它包含其他内容是一个编程错误。如果您发现它不是return
则不行。如果您要在此处查看此内容,则应为NSAssert()
。同样,如果viewArray
中的所有内容都应该响应hide
,那么如果不是,则不应该跳过它。这是许多微妙错误的根源。
更好的解决方案是在将对象添加到HideViewsService
时控制对象的添加(尽管有更好的方法可以做到这一点;我们将会这样做)。
@protocol XYZHideableView <NSObject>
- (void)hide;
@end
@interface XYZHideViewsService
- (void)addHideableView:(id<XYZHideableView>)view;
- (void)removeHideableView:(id<XYZHideableView>)view;
@end
现在,您无需担心viewArray
是否包含回复hide
的内容。
那就是说,我通常用NSNotificationCenter
来做这件事。可隐藏的视图应观察XYZHideAllHideableViews
之类的通知。当他们设置它时,他们应该隐藏自己。那你就不需要HideViewsService
了。您只需要一个+[HideableView hideAllHideableViews]
类方法。
答案 1 :(得分:3)
如果你想在没有警告的情况下进行编译,你可以检查对象是否符合协议,然后将其转换为id<Protocol>
:
if ([view conformsToProtocol:@protocol(Protocol)]) {
id<Protocol> conformingView = (id<Protocol>)view;
// or
UIView<Protocol> *conformingView = (UIView<Protocol>*)view;
}
答案 2 :(得分:1)
使用检查对象是否符合协议的标准方法:
if ([object conformsToProtocol:Protocol]) {
[array addObject:object];
}
我可以建议使用快速枚举吗?
-(void)hideAllViews
{
for(CustomView *view in self.viewArray)
{
if([view respondsToSelector:@selector(hide)])
{
[view performSelector:@selector(hide)];
}
}
}
答案 3 :(得分:1)
if([obj respondToSelector:selector){
[obj performSelector:selector
}