Last Updated: February 25, 2016
· anthonylevings

Introspection in Xcode for iOS (sample code)

To understand this protip, all you need to know is in the code comments.

If you call your project Introspection (and use the Class Prefix Introspection) then you can replace your entire IntrospectionViewController.m file with the following text and without altering anything else in your project it will run:

#import "IntrospectionViewController.h"

@interface IntrospectionViewController ()


@implementation IntrospectionViewController

// because Objective-C is a dynamic language it is more common to use id to describe the object being sent to methods than the actual class name but if we try to manipulate an object from a class that can't handle the message it is sent then our program will crash 
    // This is why we need to use INTROSPECTION as outlined here:
    if ([view respondsToSelector:@selector(text)]&&[view respondsToSelector:@selector(textRectForBounds:limitedToNumberOfLines:)])
// First we check the class of object our method has been sent by testing it against one or more selectors of the class we want to manipulate with this method (see Matt Neuburg, Programming iOS 5, p. 240)
        [(UILabel *)view setText:@"Hello World"];
// Since we are now pretty certain the object we have received is a UILabel or at the very least that the object will have a text property we can set the text.
// Here I've typecast the view object using (UILabel *) to declare that this is what I'm expecting - the compiler doesn't complain in this instance if (UILabel *) is removed BUT it makes things more transparent and explains why I chose the selectors that I did

- (void)viewDidLoad
    [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.

    UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectMake(200, 200, 200, 200)];
// First we create the UILabel that we need for this example
    [self.view addSubview:newLabel];
// Next we add the UILabel to our view controller's topmost view as a subview
    [self helloWorld:newLabel];
// Third we send an object we know it can use (i.e. a real UILabel)
    [self helloWorld:self.view];
// Finally we send an object we know it cannot use (i.e. UIView). With introspection in place our program runs, but try taking out the introspection (i.e. the if statement in helloWorld: and the program will crash) 



Original blogpost: