Re: Implementing delegate categories for subclasses
Christiaan Hofman <[email protected]>
| Newsgroups | gmane.comp.macosx.devel |
|---|---|
| Message-ID | <[email protected]> |
On Sep 9, 2009, at 14:59, Kiel Gillard wrote:
> Ouch, that code looks like pain. Pain to define in your header file,
> pain to implement simple interaction with delegates and difficult to
> read for third parties.
>
> I don't know what the "right way" to do things is but I'm willing to
> throw my opinion in the fire to better my own code practices and the
> practices of others. My two cents are inspired by the example of the
> NSTableView delegate. For all the optional methods in the protocol,
> NSTableView would have to test if the delegate responds to the
> optional method and then invoke it. Ugh. With a category of
> NSObject, NSTableView can happily call this optionally overridden
> delegate method and the default implementation can simply be a no-op.
>
> Personally, I define my delegate methods as categories of NSObject,
> throwing exceptions when the required methods are not implement (a
> la NSTableDataSource). If the most trivial testing doesn't expose
> the exceptions then the implementation doesn't deserve to be
> required. I figured the repetition of typing [foo
> respondsToSelector:@selector(bar:)] was tiresome and unnecessary as
> I explained in the example above.
>
> Goodnight all,
>
> Kiel
> "Home is not where you are born, but where your heart finds peace."
> Tommy Nordgren
But the whole point of my question is that on 10.6, classes like
NSTableView DO NOT define delegate methods in categories of NSObject,
but rather define FORMAL protocols, and the delegate is types as such.
That's a fact. My point is that ignoring this fact will give me loads
of compiler warnings, and that's what I want to avoid.
And throwing an exception is definitely the wrong thing to do. Most
delegate methods should NOT be required.
So I completely disagree with you on this.
Christiaan
> On 09/09/2009, at 10:39 PM, Christiaan Hofman wrote:
>
>> As you all know SL has replaced all informal delegate protocols by
>> formal protocols. This gives me some problems when subclassing
>> classes that should extend such a protocol. In particular if I want
>> to be able to use the same code for both the 10.6 and 10.5 SDK.
>>
>> The docs recommend implementing empty protocols for the new NS ones
>> conditional on using an old SDK (MAC_OS_X_VERSION_MAX_ALLOWED).
>> However, I have yet not been able to find any recommendations how
>> best to handle subclasses, in particular in this situation.
>>
>> So would someone on this list have an idea what the best way is to
>> handle this situation?
>>
>> A big problem is the fact that @optional is not supported with the
>> 10.5 SDK. The only way I can think of is to add it conditionally on
>> the SDK, and use an informal protocol for 10.5.
>>
>> Here are some things I tried. Take as an example an NSTableView
>> subclass.
>>
>>
>> @protocol MYTableViewDelegate <NSTableViewDelegate>
>> #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
>> @end
>> @interface NSObject (MYTableViewDelegate)
>> #else
>> @optional
>> // extra delegate methods here
>> @end
>>
>> @interface MYTableView : NSTableView {
>> // extra ivars here
>> }
>> // extra method declarations here
>> - (id<MYTableViewDelegate>)delegate;
>> - (void)setDelegate:(id<MYTableViewDelegate>)newDelegate;
>> @end
>>
>> @implementation MYTableView
>> // extra method implementations here
>> - (id<MYTableViewDelegate>)delegate {
>> return (id<MYTableViewDelegate>)[super delegate];
>> }
>> - (void)setDelegate:(id<MYTableViewDelegate>)newDelegate {
>> [super setDelegate:newDelegate];
>> }
>> @end
>>
>>
>> However, this gives warnings when using the 10.5 SDK when I try to
>> use the delegate with my new delegate methods, because the
>> MYTableViewDelegate protocol is empty. However, when I don't
>> override the -delegate and -setDelegate methods, I get warnings
>> when using the 10.6 SDK, because the delegate is only conforming to
>> NSTableViewDelegate.
>>
>> So my question is whether I'm doing things right this way, how to
>> do it better, and what would be the recommended way to handle this?
>> Perhaps we can get some discussion going here that would make some
>> recommendations going into the docs.
>>
>> thanks,
>> Christiaan