代码之家  ›  专栏  ›  技术社区  ›  Jaka Jančar

在需要使用委托的情况下对类进行子类化

  •  1
  • Jaka Jančar  · 技术社区  · 15 年前

    比如说你想要子类 UIScrollView 创造 UITableView ,并且您不想使用任何私有接口。

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

    我现在要做的是:

    1. 创造 UITableViewDelegate 扩展的协议 滚动视图委托 协议。
    2. 创造 UITableViewDelegateProxy ,我设置为 super.delegate UITababVIEW init .

      这个等级符合 滚动视图委托 并且有一个 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];
      }
      

      所以到目前为止,这个类是完全透明的,并且是未来的证明 滚动视图委托 扩展。

      然后,我为一些委托方法添加实现,以更改默认行为或添加更多行为(例如,调用 下一个 表视图:将显示单元格:ForRowatindexPath: 在里面 滚动查看滚动 )

    3. 重写 delegate setDelegate: 在里面 UITababVIEW 返回并设置 super.delegate.next 而不是 超级代表 . 我还将协议从 滚动视图委托 委托协议 .

    如果可以的话 UISCLVIEW 正在通过其IVAR直接访问代理。如果它使用getter,它不会返回我们的代理,而是返回由类的用户设置的代理。不管怎样,我们不能依赖这种行为。(仅供参考: UISCLVIEW 它有时会通过吸气剂,但并不总是如此)。

    因此,如果我们继续使用这个例子,问题是: 我们如何实现UITableView, 和今天一样 我们自己?

    1 回复  |  直到 15 年前
        1
  •  1
  •   John Calsbeek    15 年前

    你不能这样做,不能保留合同,这很不幸。这有点不寻常 UITableView 继承自 UIScrollView ;在桌面可可方面, NSTableView 不从继承 NSScrollView .