I recently began trying my hand at using protocols in my Objective-C development as an (obvious) means of delegating tasks more appropriately among my classes. I completely understand the basic notion of protocols and how they work. However, I came across a roadblock when trying to create a custom protocol that in turn implements another protocol. I since discovered the solution, but I am curious why the following DOES NOT work:
@protocol STPickerViewDelegate < UIPickerViewDelegate >
- ( void )customCallback;
@end
@interface STPickerView : UIPickerView
{
id < STPickerViewDelegate > delegate;
}
@property ( nonatomic, assign ) id < STPickerViewDelegate > delegate;
@end
Then in a view controller, which conforms to STPickerViewDelegate
:
STPickerView * pickerView = [ [ STPickerView alloc ] init ];
pickerView.delegate = self;
- ( void )customCallback
{
...
}
- ( NSString * )pickerView:( UIPickerView * )pickerView titleForRow:( NSInteger )row forComponent:( NSInteger )component
{
...
}
The problem was that pickerView:titleForRow:forComponent:
was never being called. On the other hand, customCallback
was being called just fine, which isn't too surprising. I don't understand why STPickerViewDelegate
, which itself conforms to UIPickerViewDelegate
, does not notify my view controller when events from UIPickerViewDelegate
are supposed to occur. Per my understanding of Apple's documentation, if a protocol (A) itself conforms to another protocol (B), then a class (C) that conforms to the first protocol (A) must also conform to the second protocol (B), which is exactly the behavior I want and expected.
What I ended up doing was removing the id< STPickerViewDelegate > delegate
property from STViewPicker
and instead doing something like the following in my STViewPicker
implementation where I want to evoke customCallback
:
if ( [ self.delegate respondsToSelector:@selector( customCallback ) ] )
{
[ self.delegate performSelector:@selector( customCallback ) ];
}
This works just fine, but I really am puzzled as to why my original approach did not work.