objective-carchitecturemessage-forwarding

Defining a class that uses different classes depending on the platform


I want to be able to have two classes that are responsible to respond to selectors differently depending if the platform is iOS or OSX.

However, I want to have code that uses only one class, and I want to avoid repeating #ifdefs.

Ideally I would want to have 3 classes:

iOSSpecificClass and OSXSpecificClass both extend UniversalClass. All calls would be done to UniversalClass, and that class is responsible to call the respective methods of iOSSpecificClass and OSXSpecificClass.

There are two solutions that I came up with:

@interface UniversalClass : NSObject

+ (void) universalMethod;

@end

@implementation UniversalClass

+(id)forwardingTargetForSelector:(SEL)aSelector {
    #if TARGET_OS_IPHONE
        return [iOSSpecificClass class];
    #else
        return [OSXSpecificClass class];
    #endif
}

@end

The problem with this approach is that UniversalClass promises something in the .h that can or cannot deliver. The warnings also tell us that. Grr. Warnings.

The second approach would be like this:

@implementation UniversalClass

+ (Class)correctClass {
    Class aClass = Nil;

    #if TARGET_OS_IPHONE
        aClass = [iOSSpecificClass class];
    #else
        aClass = [OSXSpecificClass class];
    #endif

    return aClass;
}

+ (void)universalMethod {
    Class masterClass = [UniversalClass correctClass];
    [masterClass universalMethod];
}
@end

The problem with this approach is that I have to perform changes for every method I add and I feel that I am kinda repeating myself without needing.

What are the edge cases I have to pay attention to in both solutions? Is there any better solution than those?


Solution

  • One option is to have a common header file and two different implementations for two targets (one for OSX and another for iOS) that both import and implement the header methods.

    Something like this:

    enter image description here