Say for example you want to subclass UIScrollView
to create UITableView
, and you don't want to use any private interfaces.
In order to load cells, you must use the the parent's delegate (scrollViewDidScroll
in UIScrollViewDelegate
). Additionaly, you want to add some of your own methods to the delegate (e.g. tableView:willDisplayCell:forRowAtIndexPath:
).
What I do now is:
- Create
UITableViewDelegate
protocol which extendsUIScrollViewDelegate
protocol. Create
UITableViewDelegateProxy
, which I set assuper.delegate
, inUITableView
'sinit
.This class conforms to
UIScrollViewDelegate
and has anext
property, which may reference an object conforming toUITableViewDelegate
.By default, it tries to respond using it's own implementation. If that isn't available, it tries with the
next
's implementations, otherwise it doesn't respond.- (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]; }
So up to now, this class is totally transparent and future-proof if
UIScrollViewDelegate
is extended.Then I add implementations for some of the delegate methods to change the default behavior or add some more behavior (e.g. call
next
'stableView:willDisplayCell:forRowAtIndexPath:
inscrollViewDidScroll
).Override
delegate
andsetDelegate:
inUITableView
to return and setsuper.delegate.next
instead ofsuper.delegate
. I also change the protocol fromUIScrollViewDelegate
toUITableViewDelegate
.
This works OK if UIScrollView
is accessing the delegate via it's ivar directly. If it uses the getter, it will not return our proxy, but instead the delegate set by the user of the class. Either way, we can't rely on this behavior. (fyi: In UIScrollView
, it goes through the getter sometimes, but not always).
So if we stay with this example, the question is: how could we implement UITableView, exactly as it is today, ourselves?