2

I'm looking for something similar to @protected for methods. @protected seems to work only on @properties (setters and getters). Is there a way to get a similar behaviour for regular methods as well?

Meda
  • 2,535
  • 3
  • 17
  • 30
  • Don't prefer "good practice" over good code. This is not something essential. Instead document your classes and write what users should and should not do. –  Feb 17 '13 at 17:07
  • 2
    possible duplicate of [Private and protected methods](http://stackoverflow.com/q/4777165/), [Is it possible to have private methods and properties visible to subclasses?](http://stackoverflow.com/q/4687103), [Is it possible to declare a method as private?](http://stackoverflow.com/q/647079), [Private method declaration ObjC](http://stackoverflow.com/q/9414410), [Best way to define private methods for a class](http://stackoverflow.com/q/172598), [Private properties and methods in ObjC](http://stackoverflow.com/q/6778933), and [more](http://stackoverflow.com/search?q=%5Bobjc%5D+private+method) – jscs Feb 17 '13 at 18:48
  • @Meda spread the wisdom... -.- If you can't live without it, you should probably quit writing Objective-C code. –  Feb 17 '13 at 22:09
  • 2
    @h2co3 You can live without many things, does't mean you have to, doesn't mean you can't look for better things. As for 'spreading wisdom', I though you were the one doing it, with things like 'Don't prefer good practice over good code', which, although it sounds good, like in 'poetry good', it's otherwise an useless contradiction. – Meda Feb 18 '13 at 04:41
  • @Meda It's not a contradiction unless you don't understand it/twist my words. Instead of worrying too much about why, how and who will abuse the private methods of your class, you should focus on writing, structuring and documenting your code well. –  Feb 18 '13 at 05:53

4 Answers4

4

Based on your comments, I assume you're talking about hiding from the compiler. Which is indeed possible, but probably a little bit cumbersome. Hiding from the runtime is impossible on the other hand, one way or another if someone really wants to access your method, they will.

To hide from the compiler, you should define a class extension in a separate header file like this:

#import "MyClass.h"

@interface MyClass ()

@property (nonatomic, strong) NSObject* protectedObject;
-(void) protectedMethod;

@end

You could call the header MyClass+Internal.h and if you're building a library, set the header visibility to private

Now all you have to do is import your private header in the subclasses implementation files (or wherever you may want to use the methods internally)

Community
  • 1
  • 1
Valentin Radu
  • 8,353
  • 8
  • 57
  • 89
  • This is the best way of doing this that I have found, and have used it myself in the past. I do try to avoid it though (there is usually a better way). – lnafziger Feb 17 '13 at 17:57
  • Thank you! Seems to be working fine, exactly what I've wanted. (I realize that you can't really hide from the runtime, but it helps to have a clean autocompletion list. – Meda Feb 17 '13 at 18:03
  • @Meda, glad it helped you. – Valentin Radu Feb 17 '13 at 18:06
  • 1
    This is basically what is done for writing custom `UIGestureRecognizer` subclasses in iOS. I'd recommend one key change to this answer though. Don't make this a "private" category. Change `@interface MyClass ()` to something like `@interface MyClass (ProtectedMethods)`. See `UIGestureRecognizerSubclass.h` in iOS for an example. – rmaddy Feb 17 '13 at 18:26
  • 2
    @rmaddy The extension allows you to keep your internal methods and properties declarations in one place, whereas using a category will force you to separate them (Unlike regular categories, `class extensions can add their own instance variables to a class. Declaring the properties this way will make the compiler automatically synthesize the relevant accessor methods, as well as an instance variable, inside the primary class implementation.`) Why do you think a category is better? – Valentin Radu Feb 17 '13 at 19:18
  • @ValentinRadu My response was based on what Apple is doing with `UIGestureRecognizerSubclass.h`. A category still lets you declare protected properties and methods. Using a category for this allows you to still use a class extension for other needs (if any). – rmaddy Feb 17 '13 at 19:34
  • 1
    Using a class extension like this still allows you to use a class extension declared in another place for other needs. A category lets you declare protected properties true, but you'll have to handle yourself the corresponding instance variables, that's why I highlighted the above quote. You just end up writing more, duplicating the things the compiler can do for you, without any true gain in my opinion. – Valentin Radu Feb 17 '13 at 19:42
0

There's no per-method access control in Objective-C.

You can split the API into several categories and put them into different header files to achieve some kind of advisory access control.

Nikolai Ruhe
  • 79,600
  • 16
  • 173
  • 195
0

I've seen this implemented in the wild via a named (as opposed to anonymous) category in the .h file:

//MyClass.h:

@interface MyClass : NSObject
  /*Public stuff...*/
@end


@interface MyClass (protected)
  /*Protected stuff...*/
@end

But as others have mentioned, this named category is really just a way to provide a bit of a hint — and one that relies on developers looking at a .h file instead of documentation. It doesn't do anything magical and doesn't implement any real access control.

Also on the topic of protected methods in ObjC, remember that Cocoa is set up to favor composition and delegation over inheritance. If you find yourself working too hard, you might be swimming up stream.

jemmons
  • 18,194
  • 6
  • 53
  • 83
-1

You can neither declare a method protected or private. Declaring a method "private" as you mention above is just fakery, and doesn't really stop anything. Objective-C's dynamic nature makes it impossible to implement access controls for methods. (You could do it by heavily modifying the compiler or runtime, at a severe speed penalty, but for obvious reasons this is not done.)

sources:

Protected methods in Objective-C

http://objectmix.com/c/177901-methods-access-modifiers-objective-c.html

You can apparently simulate this functionality with some workarounds, but I doubt that is good style.

Community
  • 1
  • 1
Hunter McMillen
  • 52,839
  • 21
  • 105
  • 154
  • 2
    I don't want to stop anybody from doing anything, I just want to give them a hit that they can't use the method directly, only subclasses can. I was wondering, how does Apple hide the private methods? You can surely access them, but they are inherited hidden. – Meda Feb 17 '13 at 17:15