Re: Implementing delegates with formal protocols
Re: Implementing delegates with formal protocols
- Subject: Re: Implementing delegates with formal protocols
- From: tyler <email@hidden>
- Date: Fri, 28 Aug 2009 17:29:50 -0700
On Aug 28, 2009, at 3:02 PM, Corbin Dunn wrote:
On Aug 28, 2009, at 2:57 PM, Rick Mann wrote:
Thanks for the suggestions. I have one suggestion saying to extend
my protocol to conform to NSObject, and another saying I should use
NSObject instead of ID.
Is one approach better than the other?
Yes; David's suggestion is preferred. It is what we did in AppKit
for SnowLeopard, ie:
@protocol NSControlTextEditingDelegate <NSObject>
The main reason is so controls can store a reference and do a -
respondsToSelector: on @optional methods.
corbin
Unfortunately David's suggested approach doesn't work (on the iPhone
3.0 sdk anyway) if you are calling your delegate from a background
thread and the delegate expects to only be called on the main thread.
In this case you probably want to call the methods of your delegate via:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg
waitUntilDone:(BOOL)wait;
e.g., [delegate performSelectorOnMainThread: ....];
but you get warnings during compile if you try this with a delegate
declared as
id<protocolName> delegate;
The approach I noted:
@protocol fooDelegate
- (void) tellMe;
@end
@interface foo : NSObject
{
NSObject<fooDelegate>* delegate;
}
...
@end
works around that.
It occurs to me now that another, likely better, alternative is to do
the move from background thread to main thread inside the class
containing the delegate instance variable and only then call the
delegate method. Maybe that's cleaner; it does require you to create
extra internal methods for all the delegate protocol methods...
So instead of calling
[delegate performSelectorOnMainThread: @selector(tellMe) .....]
the class calls an internal method on the main thread:
[self performSelectorOnMainThread: @selector(tellDelegateTellMe) ....]
and then this internal method calls the delegate directly now that we
are on the main thread, something like:
// called on main thread
- (void) tellDelegateTellMe
{
// maybe add: NSAssert( [NSThread isMainThread],
@"tellDelegateTellMe called on background thread!" );
[delegate tellMe];
}
interesting option, though more code to type in :)
Perhaps someone has a better alternative.
tyler
(none of this code has been compiled, just typed in for illustrative
purposes)
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden