objective-cioscocoa-touchios-3.x

Confusion concerning NSClassFromString / Checking for Gesture Recognizer


I'm trying to use NSClassFromString to prevent a block of code from running on pre iOS 3.2 devices. The code block in question is as follows:

if (NSClassFromString(@"UITapGestureRecognizer"))
{
    UITapGestureRecognizer *tap = [[[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard)] autorelease];
    [tap setCancelsTouchesInView:NO];
    [[self view] addGestureRecognizer:tap];
}

I'm doing this because Apple's documentation states that UITapGestureRecognizer is incompatable with pre 3.2 installations. https://developer.apple.com/library/ios/#documentation/uikit/reference/UITapGestureRecognizer_Class/Reference/Reference.html

I originally thought that using NSClassFromString would return nil when I ran it on this device, but it does not. The statement is true and the code executes. (An interesting note, the code sort of works on a pre 3.2 installation.)

Anyway, I'd like to know why NSClassFromString is NOT returning nil, and is there anything I can do otherwise to accomplish what I'm trying to do?

enter image description here


Solution

  • From the docs

    Usage Special Considerations

    To determine whether a class is available at runtime in a given iOS release, you typically check whether the class is nil. Unfortunately, this test is not cleanly accurate for UIGestureRecognizer. Although this class was publicly available starting with iOS 3.2, it was in development a short period prior to that. Although the class exists in an earlier release, use of it and other gesture-recognizer classes are not supported in that earlier release. You should not attempt to use instances of those classes.

    To determine at runtime whether you can use gesture recognizers in your application, test whether the class exists and, if it does, allocate an instance and see check if it responds to the selector locationInView:. This method was not added to the class until iOS 3.2. The code might look like the following:

    UIGestureRecognizer *gestureRecognizer = [[UIGestureRecognizer alloc] initWithTarget:self action:@selector(myAction:)];
     
    if (![gestureRecognizer respondsToSelector:@selector(locationInView:)]) {
        [gestureRecognizer release];
        gestureRecognizer = nil;
    }
    // do something else if gestureRecognizer is nil