在需要使用委托时对类进行子类化

时间:2009-08-11 08:30:18

标签: objective-c cocoa

例如,您想要创建UIScrollView的子类UITableView,并且您不想使用任何私有接口。

要加载单元格,您必须使用父级委托(scrollViewDidScroll中的UIScrollViewDelegate)。另外,您想要向委托添加一些自己的方法(例如tableView:willDisplayCell:forRowAtIndexPath:)。

我现在所做的是:

  1. 创建扩展UITableViewDelegate协议的UIScrollViewDelegate协议。
  2. UITableViewDelegateProxy的{​​{1}}中创建super.delegate,我将其设置为UITableView

    此类符合init并且具有UIScrollViewDelegate属性,可能引用符合next的对象。

    默认情况下,它会尝试使用自己的实现进行响应。如果没有,它会尝试使用UITableViewDelegate的实现,否则它不会响应。

    next

    到目前为止,如果扩展- (BOOL)respondsToSelector:(SEL)aSelector { if ([super respondsToSelector:aSelector]) return YES; else if (self.next) return [self.next respondsToSelector:aSelector]; else return NO; } - (void)forwardInvocation:(NSInvocation *)anInvocation { // self did not respond to selector if (self.next) [anInvocation invokeWithTarget:self.next]; else [self doesNotRecognizeSelector:anInvocation.selector]; } ,这个课程完全透明,面向未来。

    然后我添加了一些委托方法的实现来更改默认行为或添加更多行为(例如在UIScrollViewDelegate中调用next的{​​{1}}。)

  3. 覆盖tableView:willDisplayCell:forRowAtIndexPath:中的scrollViewDidScrolldelegate,以返回并设置setDelegate:而不是UITableView。我还将协议从super.delegate.next更改为super.delegate

  4. 如果UIScrollViewDelegate通过它的ivar直接访问委托,这可以正常工作。如果它使用getter,它将不会返回我们的代理,而是返回由该类用户设置的委托。无论哪种方式,我们都不能依赖这种行为。 (fyi:在UITableViewDelegate中,它有时会通过吸气剂,但并非总是如此)。

    因此,如果我们继续这个例子,问题是:我们如何实现UITableView,完全像现在这样,我们自己?

1 个答案:

答案 0 :(得分:1)

你不能这样做并保留合同,这是不幸的。 UITableView继承自UIScrollView,这有点不寻常;在桌面Cocoa方面,NSTableView不会从NSScrollView继承。