Objects (Part 5): Introspection

  • Introspection is that ability to ask questions about a class and find out more of its properties. This is a fundamental concept of a group of concepts known as polymorphism, dynamic typing, and dynamic binding, which form a central tenet of object-oriented programming. Before we begin, there is another part of the language that we have to cover. 

    Selector (@selector())

    Remember how methods are also known as selectors (because a method is selected at runtime)? Turns out, you can select a method yourself, and pass it as an argument to a method. The syntax is simple:


    Remember that a method name includes its colons, such as setNumerator:overDenominator: (if appropriate).

    You can declare a selector as a variable to be used in multiple places with the following syntax:

    SEL action = @selector(doSomethingWithObject:)

    Note that a selector is of type SEL.

    Introspection Methods

    Here is a list of most of the introspection methods. A few deal with some more advanced topics, such as protocols; they will be introduced in context. Note that the classType argument refers to an object’s class, which is returned by invoking the class method, as in [Fraction class];.

    • -(BOOL)isKindOfClass:classType
      Is the object a member of that class or a subclass?
    • -(BOOL)isMemberOfClass:classType
      Is the object a member of that class?
    • -(BOOL)respondsToSelector:aSelector
      Does an object (class or instance) respond to the selector’s method?
    • +(BOOL)instancesRespondToSelector:aSelector
      Do instances of the class respond to the selector’s method?
    • +(BOOL)isSubclassOfClass:classType
      Is this class a subclass of the specified class?
    • -(id)performSelector:aSelector
      Ask the class to perform the method specified by the selector, returning whatever the method is intended to return.
    • -(id)performSelector:aSelector withObject:someObject
      Performs the selector, passing in someObject as the first (and hopefully only) argument, returning whatever the method is designed to return.
    • -(id)performSelector:aSelector withObject:someObject withObject:anotherObject
      Perform the selector, passing in the two arguments in that order to the (assumed) two parameters defined by the selector, returning whatever the method is designed to return.

    Working off our Fraction and MixedNumber classes, we can have the following routine:

    int main (int argc, const char * argv[]) {
    	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];	Fraction *frac = [[Fraction alloc] init];
    	MixedNumber *mn = [[MixedNumber alloc] init];
    	if ([frac isMemberOfClass:[Fraction class]])
    		NSLog(@"frac is member of Fraction class");
    	if ([mn isMemberOfClass:[Fraction class]])
    		NSLog(@"mn is member of Fraction class");
    	if ([mn isMemberOfClass:[NSObject class]])		// Remember that everything
    		NSLog(@"mn is member of NSObject class");	// inherits from NSObject
    	if ([frac isKindOfClass:[Fraction class]])
    		NSLog(@"frac is kind of Fraction class");
    	if ([mn isKindOfClass:[Fraction class]])
    		NSLog(@"mn is kind of Fraction class");
    	if ([frac isKindOfClass:[NSObject class]])
    		NSLog(@"frac is kind of NSObject class");
    	if ([frac respondsToSelector:@selector(add:)])
    		NSLog(@"frac responds to add:");
    	if ([mn respondsToSelector:@selector(add:)])
    		NSLog(@"mn responds to add:");
    	if ([Fraction respondsToSelector:@selector(alloc)])
    		NSLog(@"Fraction class responds to alloc");
    	if ([Fraction instancesRespondToSelector:@selector(subtract:)])
    		NSLog(@"Instances of Fraction respond to subtract:");
    	if ([MixedNumber isSubclassOfClass:[Fraction class]])
    		NSLog(@"MixedNumber is a subclass of Fraction");
    	[frac release];
    	[mn release];
        [pool drain];
        return 0;

    The output is

    frac is member of Fraction class
    frac is kind of Fraction class
    mn is kind of Fraction class
    frac is kind of NSObject class
    frac responds to add:
    mn responds to add:
    Fraction class responds to alloc
    Instances of Fraction respond to subtract:
    MixedNumber is a subclass of Fraction

    Introspection really isn’t a difficult topic—the only potential source of error stems from confusing the functionality of isKindOfClass: and isMemberOfClass:. Somehow, just remember that isKindOfClass: involves descendants (subclasses), while isMemberOfClass: does not.

  • Advertisements
    Leave a comment


    1. Roberto

       /  October 27, 2011

      I hadn´t understood this concept in Apple´s documents but it is very concise and clear here. ( I guess We need to extend it on our own )

    1. Objects (Part 6): Dynamic Typing « Programming for iOS
    2. Learn Objective-C in 24 Days « Programming for iOS

    Leave a Reply

    Fill in your details below or click an icon to log in: Logo

    You are commenting using your account. Log Out /  Change )

    Google photo

    You are commenting using your Google account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s

    • Welcome

      My goal is to make CupsOfCocoa into a beautiful source for beginners to the iPhone platform to get started. Subscribe below for more, and stay tuned!

    • Contact Me

      If you need to contact me for any reason, feel free to send me an email.
    • The Giving Spirit

      If you've found this site helpful, would you consider donating a little sum? Any amount is appreciated...Thanks so much!

    • Roadmap

    • Enter your email address to follow this blog and receive notifications of new posts by email.

      Join 222 other followers

    • Back to the Past

      February 2011
      S M T W T F S
      « Jan   Mar »
    • Time Machine

    • You count!

    • Worldwide Stats

      free counters
    • Advertisements
    %d bloggers like this: