Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: respondsToSelector - #import OR compiler warnings?



Steve followed up to my response off-list.

My original post was... terse. I have had my coffee now. Let me clarify a bit more...

On Dec 30, 2008, at 10:52 AM, Steve Cronin wrote:
You seem to be saying that I should have ALL the impacted methods visible in my category declaration.
Don't 'hide' them by burying them inside -peformSelector().
Is that accurate?

Correct. It is sort of an either/or situation.

If you want to use -performSelector:, then the compiler will never warn because there will be no expression that uses the method declaration to warn about.

However, -performSelector: is slower and can hide problematic invocations exactly because the compiler cannot validate the argumentation to the method. As well, -performSelector: cannot be used with non-object arguments. You couldn't pass an (NSRect) parameter via -performSelector:, for example.

For those reasons, -performSelector: is not typically used. Instead, you declare the method somewhere sensible and then simply invoke the method after testing to see if the object responds to the selector.

For the delegation pattern, the declarations are hung off of NSObject in the form of informal protocols (which are really just a category @interface with no corresponding @implementation).

For example, NSTableView declares:

@interface NSObject(NSTableViewDelegate)

- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn: (NSTableColumn *)tableColumn row:(NSInteger)row;
...
@end


And then used something like:

if ([delegate respondsToSelector :@selector(tableView:willDisplayCell:forTableColumn:row:)])
[delegate tableView: self willDisplayCell: cell forTableColumn: tc row: 42]; // you get the idea...


This has several advantages. Primarily, it works -- neither of the above methods could be used with -performSelector: variants. Also, it is faster and the compiler validates the types of the arguments properly.

Because the delegate can be an instance of *any* class, the declaration off of NSObject is accurate.

If the methods you are interested in will *always* be implemented on subclasses of a particular class, declare them in an informal protocol of that class.

Alternatively, you could implement the methods in that class directly as no-ops and then just always call 'em without testing via - respondsToSelector:. This is commonly done when using an abstract class and specific subclasses.

As an example, consider NSView. NSView implements -drawRect:, which does absolutely nothing. But by implementing that method, then NSView can call -drawRect: on subviews with impunity.

Is there no overhead at all for a category declaration?

Nope. None. An informal protocol declaration -- a category declaration with no corresponding @implementation -- is only considered at compile time. None of the information contained in the informal protocol will survive through to the runtime.


b.bum

_______________________________________________

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:
http://lists.apple.com/mailman/options/cocoa-dev/email@hidden

This email sent to email@hidden
References: 
 >respondsToSelector - #import OR compiler warnings? (From: Steve Cronin <email@hidden>)
 >Re: respondsToSelector - #import OR compiler warnings? (From: Graham Cox <email@hidden>)
 >Re: respondsToSelector - #import OR compiler warnings? (From: Steve Cronin <email@hidden>)
 >Re: respondsToSelector - #import OR compiler warnings? (From: Steve Cronin <email@hidden>)
 >Re: respondsToSelector - #import OR compiler warnings? (From: Bill Bumgarner <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.