Reputation: 11596
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:
UITableViewDelegate
protocol which extends UIScrollViewDelegate
protocol.Create UITableViewDelegateProxy
, which I set as super.delegate
, in UITableView
's init
.
This class conforms to UIScrollViewDelegate
and has a next
property, which may reference an object conforming to UITableViewDelegate
.
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
's tableView:willDisplayCell:forRowAtIndexPath:
in scrollViewDidScroll
).
Override delegate
and setDelegate:
in UITableView
to return and set super.delegate.next
instead of super.delegate
. I also change the protocol from UIScrollViewDelegate
to UITableViewDelegate
.
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?
Upvotes: 1
Views: 454
Reputation: 36497
You can't do it and preserve the contract, which is unfortunate. It's somewhat unusual that UITableView
inherits from UIScrollView
; on the desktop Cocoa side of things, NSTableView
does not inherit from NSScrollView
.
Upvotes: 1