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