Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C Private Method Dilemma

I'm aware that Objective-C doesn't support real private methods. What I'm currently doing to declare 'private' methods is adding the following to class .m files:

@interface MyClass() 

- (void) privateMethodName;

@end


The Problem:

If I now add a subclass, and want to use this 'private' method, I can't! I get the error:

Receiver type 'SubClassName' for instance message does not declare a method with selector 'privateMethodName'


So, if I don't want non-subclasses to be able to access this method, but do want subclasses to be able to, what can I do? What is the best/proper way of achieving my goal?

like image 436
Jordan Smith Avatar asked Jan 06 '12 09:01

Jordan Smith


2 Answers

You could separate the "protected" interface from the public one. In the primary header, just declare the public methods:

MyMagicThingy.h:

@interface MyMagicThingy: NSObject

- (void) publicMethod;

@end 

Then, have an additional header with protected methods:

MyMagicThingy+Protected.h:

#import "MyMagicThingy.h"

@interface MyMagicThingy (Protected)

- (void) protectedMethods;

@end

You cannot have "real" private/protected/public methods in Objective C (as in: the compiler will enforce access rules. All methods are public). You have to go with a convention.

like image 182
Dirk Avatar answered Sep 23 '22 22:09

Dirk


What you describe is really a protected method. One approach to overcome this: Ivars can be declared @public, @protected, or @private. You could declare a protected helper instance to restrict access to derived instances, which then calls back through the object which holds it.

Another alternative in some cases would be to make the subclasses write to an interface, then keep your implementation private.

Sometimes, you just have to document "don't do this, unless you are not a subclass" because it's not part of the language. In this mindset, a separate header which declares a category of protected methods is one of my favorite. It's pretty well hidden from clients, but can be made visible to subclasses by explicit inclusion -- Dirk provided an example of this at the same time, check it out.

Lastly, if you're comfortable with ObjC++, C++ offers this control, so you can mix modes and visibility quite freely.

like image 23
justin Avatar answered Sep 25 '22 22:09

justin