使用选择器或块将协议的基类属性设置为方法

时间:2012-08-17 13:33:22

标签: objective-c selector objective-c-blocks class-method

我正在创建一个用于iOS网格视图的接口/协议。我试图在类中封装尽可能多的信息,只留下很少的信息给类及其子类的用户。 我坚持回调方法或委托应该是什么。 在C或C ++中,我需要一个函数指针作为参数传递给将在touch up事件上调用的方法。 在Objective C(我相当新),我对块和选择器感到困惑。从我所看到的Apple方式是使用选择器。因此,此类应该要求将一个方法设置为选择器,以便在检测到触摸事件时发生什么。我不想做大量的子类化,因为这将限制可重用性并在每次使用此接口时强制执行更多编码。我使用选择器包含有限的代码,到目前为止我所做的事情,但我愿意接受关于如何用块来完成同样的建议以及为什么它会更好。我没有测试过这个,我正在设计它。

@protocol Grid <NSObject>
@required

/*! @brief Initializer for base class */
- (id) init:(UIView *)parent withSelector:(SEL)selector;
/*! @brief Draw the actual view */
- (void) draw:(CGRect) rect;
/*! @brief Reload the data */
- (void) reload;
@end

这个标题具有误导性,自从发布这个问题以来,我已经更好地了解了Objective-C中的工作原理。这是关于抽象基类,继承和多态,而不是将选择器设置为属性或委托

1 个答案:

答案 0 :(得分:1)

您应该做的是要求类(可能是委托)符合您的协议。你可以这样做。

@interface GridView : UIView {
    id<Grid> delegate;
}

...

@end

并让用户指定delegate属性。此时,您对委托的所有了解都是它符合Grid协议,因此您可以确保它实现了所有必需的方法。请注意,协议中永远不应该有任何类型的init方法,因为您的类(GridView)永远不必分配自己的委托,这完全违背了目的。

在您将要用作委托的类中,您必须确保它符合Grid协议,以便可以将其用作委托。这看起来像这样。

@interface GridDelegateObject : NSObject <Grid> {
...
}

...

@end

并且您必须至少为Grid协议中的所需方法提供实现。

然后您应该将GridView实例的委托设置为GridDelegateObject的实例。

[gridViewInstance setDelegate:gridDelegateObjectInstance];

然后您可以调用gridDelegateObject Grid协议中gridViewInstance实施的所有方法,就像这样。

-(void)someMethod {
    [delegate reload];
}

或类似的东西。这将调用gridDelegateObjectInstance上的重新加载功能。