Re: Class introspection [was Re: Forcing allocation of a subclass]
Re: Class introspection [was Re: Forcing allocation of a subclass]
- Subject: Re: Class introspection [was Re: Forcing allocation of a subclass]
- From: Jean-Daniel Dupas <email@hidden>
- Date: Sun, 25 Jan 2009 20:50:52 +0100
Le 25 janv. 09 à 19:54, João Varela a écrit :
On 2009/01/25, at 18:02, João Varela wrote:
So you mean that
if ( self == [aReceiver class] )
is the same as
if ( [self class] == [aReceiver class] ) ?
Yes it is.
Just a simple snippet to try to help you to understand.
We are ok to say that in a method, self represents the receiver.
Now have a look at this call:
[PDFDocument allocWithZone:nil]
You are ok to say that it is equivalents to:
[[PDFDocument class] allocWithZone:nil]
With the second form, you clearly see here that the receiver is
[PDFDocument class]. And as self is the receiver, (self ==
[PDFDocument class]) is perfectly valid to test class equality.
Hmm...
I think this example does not cover my doubt expressed above. I
actually now think that both examples I wrote above are wrong or at
least semantically wrong.
The thing is: 'self' is a pointer to class instance and of course
an actual parameter for the Obj-C runtime routines.
The example you gave is that you are talking about class methods
that do not and should not be used with pointers to class instances
but to receivers that are class names (in your example
'PDFDocument') or class objects returned by, using your example,
[PDFDocument class]. As far as I know class objects and class
instances are two different things.
I think the following comparison is semantically wrong:
if ( self == [MyClass class] )
This statement is comparing a pointer to an object instance (self)
to a MyClass object (returned by the invocation of +[NSObject
class] method) and these are two different animals altogether,
unless the Obj-C runtime deals with this and does the right thing.
My fix is actually semantically wrong too:
if ( [self class] == [myClass class] )
because I am using a receiver (self) that should be a class name
(but it is a pointer to a class instance) in a class method, whose
receiver must be a class name or a class object.
Actually the fix should have been:
if ( [self isKindOfClass:[myClass class]] )
because in this case -isKindOfClass is an instance method whose
receiver is a class instance, not a class object.
If my reasoning is not correct then the Obj-C runtime is rather
messy, which I think that is not the case.
JV
OK, to answer myself I just checked and the 'class' method can also
be an instance method of NSObject objects. That explains everything.
So
if ( [self class] == [myClass class] )
is as correct as
if ( [self isKindOfClass:[myClass class]] )
No, isKindOfClass check for the superclass. It returns true if self
class is myClass or a subclass of myClass.
You should use isMemberOfClass: to got something equivalent.
because in the first example we are calling -class: in [self class]
and on the right we are calling +class: in [MyClass class]. This
actually surprises me. Even though the +class: method is a NSObject
class method and -class: is part of the NSObject protocol. How is
that possible there is no collision between these two methods. Isn't
that a case of overloading???
It's perfectly legal to have class methods and instance methods with
the same name.
But there is more:
Methods of the Root Class
All objects, classes and instances alike, need an interface to the
runtime system. Both class objects and instances should be able to
introspect about their abilities and to report their place in the
inheritance hierarchy. It’s the province of the NSObject class to
provide this interface.
So that NSObject's methods don’t have to be implemented twice—once to
provide a runtime interface for instances and again to duplicate that
interface for class objects—class objects are given special
dispensation to perform instance methods defined in the root class.
When a class object receives a message that it can’t respond to with a
class method, the runtime system determines whether there’s a root
instance method that can respond. The only instance methods that a
class object can perform are those defined in the root class, and only
if there’s no class method that can do the job.
For more on this peculiar ability of class objects to perform root
instance methods, see the NSObject class specification in the
Foundation framework reference
_______________________________________________
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