2

Simply put, I need a way to have some private methods in a class that are only exposed for its subclasses, and it is difficult (maybe impossible) to do this in Objective-C.

What I did so far:

// MyClass.h

@protocol MyClassProtectedMethodsProtocol
- (void)__protectedMethod;
@end

@interface MyClass : NSObject
- (void)publicMethod;
- (id<MyClassProtectedMethodsProtocol>)protectedInstanceForSubclass:(id)subclass;
@end

Then:

// MyClass.m
#import "MyClass.h"

@interface MyClass() <MyClassProtectedMethodsProtocol>
@end

@implementation MyClass

- (void)publicMethod
{
    // something
}

- (id<MyClassProtectedMethodsProtocol>)protectedInstanceForSubclass:(id)subclass
{
    if ([subclass isKindOf:MyClass.class] && ![NSStringFromClass(subclass.class) isEqualToString:NSStringFromClass(MyClass.class)])
    {
        // the subclass instance is a kind of MyClass
        // but it has different class name, thus we know it is a subclass of MyClass
        return self;
    }
    return nil;
}

- (void)__protectedMethod
    // something protected
{
}

@end

Then the subclass of MyClass can just:

id<MyClassProtectedMethodsProtocol> protectedMethodInstance = [self protectedMethodForSubclass:self];
if (protectedMethodInstance != nil)
{
    [protectedMethodInstance protectedMethod];
}

This way does not break OO (compared to calling the private method and ignoring the compiler warning, or even guessing the private method name as only .h is known), but a protocol is needed for the available protected methods and once this is exposed, in a big project that we only deliver interface and static library to client, client can actually know the private methods and try to call them regardless of warning. And the bigest problem is from outside of the subclass, user can as well call this method to get the protectedInstance. Can anyone advice?

Thanks

hzxu
  • 5,753
  • 11
  • 60
  • 95

2 Answers2

1

A standard way to handle this scenario is to include the internal methods in a separate header, like MySuperClass_Internal.h. Use a class extension: @interface MySuperClass (Internal). Do not install MySuperClass_Internal.h at /usr/local/include or in the framework, or however you're delivering the library to your clients.

Cezar
  • 55,636
  • 19
  • 86
  • 87
Aaron Golden
  • 7,092
  • 1
  • 25
  • 31
1

Check this: Protected methods in Objective-C

Simply put, there is no way to prevent a method from being called in Objective-C, since ultimately, the client can still call performSelector on any object.

Community
  • 1
  • 1
Cezar
  • 55,636
  • 19
  • 86
  • 87
  • 3
    Instead of posting a link to a duplicate, you should vote to close the question as a duplicate. – rmaddy Mar 19 '13 at 01:39
  • @rmaddy I didn't really see this as a duplicate, since the OP tried a specific approach he wanted comments on. But I see your point. – Cezar Mar 19 '13 at 01:41