• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Class introspection [was Re: Forcing allocation of a subclass]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: Class introspection [was Re: Forcing allocation of a subclass]
      • From: João Varela <email@hidden>
References: 
 >Re: Forcing allocation of a subclass (From: João Varela <email@hidden>)
 >Re: Forcing allocation of a subclass (From: Jean-Daniel Dupas <email@hidden>)
 >Re: Forcing allocation of a subclass (From: João Varela <email@hidden>)
 >Re: Forcing allocation of a subclass (From: Jean-Daniel Dupas <email@hidden>)
 >Class introspection [was Re: Forcing allocation of a subclass] (From: João Varela <email@hidden>)
 >Re: Class introspection [was Re: Forcing allocation of a subclass] (From: João Varela <email@hidden>)

  • Prev by Date: Re: Getting pixel color from NSView
  • Next by Date: Re: Targeting Tiger
  • Previous by thread: Re: Class introspection [was Re: Forcing allocation of a subclass]
  • Next by thread: Re: Class introspection [was Re: Forcing allocation of a subclass]
  • Index(es):
    • Date
    • Thread