According to some official talk, a class in Objective-C should only expose public methods and properties in its header:
@interface MyClass : NSObject
@prope
Your only choice is to declare it as public in the header file. If you want to at least keep some method separation, you can create a category and have all your protected methods and attributes there, but in the end everything will still be public.
#import "MyClass.h"
@interface MyClass (Protected)
- (void) protectedMethods;
@end
Simply create a .h file with your class extension. Import this into your .m files. Incidentally, this is a great way to test private members without breaking encapsulation (I'm not saying you should test private methods :) ).
// MyClassProtectedMembers.h
@interface MyClass()
@property (nonatomic, strong) MyPrivateObject *privateObject;
- (void) privateMethod;
@end
/////////////////
#import "MyClassProtectedMembers.h"
@implementation MyClass
// implement privateMethod here and any setters or getters with computed values
@end
Here's a gist of the idea: https://gist.github.com/philosopherdog/6461536b99ef73a5c32a
I see good answers for making properties visible, but I don't see exposing the methods addressed very clearly in any of these answers. Here is how I have successfully exposed private methods to the subclass using a Category:
SomeSuperClass.m:
@implementation SomeSuperClass
-(void)somePrivateMethod:(NSString*)someArgument {
...
}
SomeChildClass.h
@interface SomeChildClass : SomeSuperClass
SomeChildClass.m
@interface SomeSuperClass (exposePrivateMethod)
-(void)somePrivateMethod:(NSString*)someArgument;
@end
@implementation SomeChildClass
-(void)doSomething {
[super somePrivateMethod:@"argument"];
}
@end
While the other answers are correct, I'd like to add...
Private, protected and public are available for instance variables as such:
@interface MyClass : NSObject {
@private
int varA;
@protected
int varB;
@public
int varC;
}
@end
That's because there's not even a real distinction between private and public. While the compiler may warn you about an interface missing a certain method or instance variable, your program will still work.
One way to solve this is to re-declare the property in your subclass's class extension, and then add an @dynamic
statement so that the compiler won't create an overriding implementation of that property. So something like:
@interface SuperClass ()
@property (nonatomic, strong) id someProperty;
@end
....
@interface SubClass ()
@property (nonatomic, strong) id someProperty;
@end
@implementation SubClass
@dynamic someProperty;
@end
This obviously isn't ideal because it duplicates a privately visible declaration. But it is quite convenient and helpful in some situations so I'd say evaluate on a case-by-case basis the dangers involved in this duplication vs. exposing the property in the public interface.
An alternative - that is used by Apple in UIGestureRecognizer - is to declare the property in a separate category header file explicitly named as "private" or "protected" e.g. "SomeClass+Protected.h". That way, other programmers will know they ought not import the file. But, if you don't control the code you're inheriting from, that's not an option.