Re: Using performSelector: on super
Re: Using performSelector: on super
On 5 Aug 2008, at 23:38, James Bucanek wrote:
email@hidden <mailto:email@hidden> wrote
(Tuesday, August 5, 2008 2:19 PM +0100):
Sorry for the inaccuracy.
No problem.
I of course mean that the SuperSocket class responds to the -close
method but does not declare it in its interface file. -close is
indeed
declared as a method on a SuperSocket category defined within
SuperSocket.m
I was using performSelector: merely to keep the compiler content.
Declaring a further accessible category on SuperSocket to announce
the
existence of -close accomplished the same thing.
Then let me make two points and one suggestion.
In your original code, you had
SEL closeSelector = @selector(close);
if ([SuperSocket instancesRespondToSelector:closeSelector]) {
...
This does not, as I think you believe, test to see if an object of
the class SuperSocket responds to the -close message. In fact, it
tests to see if the class object for SuperSocket responds to the
+close message. SuperSocket is a reference to the single Class
object defined for SuperSocket, it it not a proxy for an instance of
the SuperSocket class.
Are you sure about that James?
The NSObject class reference for + instancesRespondToSelector: says:
"
Returns a Boolean value that indicates whether instances of the
receiver are capable of responding to a given selector.
...
To ask the class whether it, rather than its instances, can respond to
a particular message, send to the class instead the NSObject protocol
instance method respondsToSelector:.
"
The NSObject Protocol Reference for respondsToSelector: also chips in
upon the subject:
"
You cannot test whether an object inherits a method from its
superclass by sending respondsToSelector: to the object using the
super keyword. This method will still be testing the object as a
whole, not just the superclass’s implementation. Therefore, sending
respondsToSelector: to super is equivalent to sending it to self.
Instead, you must invoke the NSObject class method
instancesRespondToSelector: directly on the object’s superclass, as
illustrated in the following code fragment.
if ([MySuperclass instancesRespondToSelector:@selector(aMethod)]) {
[super aMethod];
}
"
But I have been wrong before!
To determine if an instance of an object SuperSocket responds to a
particular method, I believe that you'd have to use SuperSocket's
Class object reference and use class_getInstanceMethod to determine
if it actually implements a -close method. If you wanted to find out
if any of its superclass' implemented it, you'd have to walk of the
chain of parent Class objects until you hit NSObject.
As for the compiler warning, that could easily be suppressed with
(believe it or not)
[(id)super close]; // superclass assumed to implement close
Now that really would have saved everyone a lot of typing. I often
cast to a specific object type, casting with id never occurred to me.
If you really want your code to dynamically alter execution
depending on whether the close method is implemented by the
superclass, I would suggest something like
try
{
[(id)super close]; // call superclass' -close, if implemented
...
}
catch
{
if (method not implemented exception)
// code that gets called if superclass doesn't implement -close
...
}
--
Exception handling might be a bit excessive here I think. If I recall
correctly It's quite a heavyweight object in Objective-C.
James Bucanek
_______________________________________________
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