5

我想允许不同视图之间的交流。

我有两个较小的视图,它们位于较大的视图之上,类似于 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
    }
}
}

谢谢!!我还在学习,所以请告诉我是否有更好的方法(不仅更简单,而且更好)。

4

4 回答 4

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]类方法。

于 2013-11-05T22:32:10.597 回答
3

如果您想在没有警告的情况下进行编译,您只需检查对象是否符合协议,然后将其转换为id<Protocol>

if ([view conformsToProtocol:@protocol(Protocol)]) {
    id<Protocol> conformingView = (id<Protocol>)view;
    // or
    UIView<Protocol> *conformingView = (UIView<Protocol>*)view;
}
于 2013-11-05T22:24:53.917 回答
1
if([obj respondToSelector:selector){
  [obj performSelector:selector
}
于 2013-11-05T22:21:06.740 回答
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)]; 
        }
    }
}
于 2013-11-05T22:19:12.827 回答