Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protected variables with modern objective-C?

Tags:

objective-c

I feel that modern Objective-C encourages using instance variables as properties for memory management and key-value observation. That works fine, and I'm using interface inside implementation file for private variables, like this:

@interface MyClass ()
@property NSObject* myVar;
@end

However, how can I make protected variables? In case above, my subclasses won't be able to see properties declared like that. I can go iVar route, but then it feels off with the rest of the code if private variables are declared like above and protected are iVars.

I've read this solution: Workaround to accomplish protected properties in Objective-C, but it seems to overcomplicate code too much.

like image 635
Rudi Avatar asked Aug 03 '13 00:08

Rudi


1 Answers

Your best option is to use a category in a second header file, e.g. MyClass_protected.h, and include it in the main class and subclasses, as suggested in the solution you link. It's really quite straightforward, not "overcomplicated" at all, just one additional file.

Objective-C has very strong introspection characteristics. No matter how or where you declare a property (or any other function, for that matter), you can access it from anywhere. You will get a compiler warning unless the code you're writing can see the corresponding declaration or implementation (unless you use an introspective method like one of the performSelector... family). The only reasons for the interface are name-safety, type-safety, and preventing compiler warnings. Therefore, you have a few options:

The main class interface

You get implementation safety (i.e. the compiler will give a warning if you don't implement a method). However, every class (that imports yours) will see the methods. You can use a comment to indicate that the method should be protected, but of course no one will see it unless they check the source. I most often use this when I'm the only programmer on a project, as I know what should be protected and what shouldn't.

A category in the same .h file

As above, programmers won't see it's protected unless they check the source, but if they do it will be much more obvious. If you declare this in a named category (@interface MyClass (protected)) you lose type safety, but it's even more clear what you intend. I most often use this to emulate abstract methods - i.e. explicitly not implementation-safe, but should be visible to everyone.

A category in the subclass's .m file directly

It's a bad idea, don't do it. You do only see the methods in the subclass, but you lose implementation safety and it really just feels wrong. I have only ever used this for unit tests, and I eventually migrated those to a separate header.

A category in a separate header (MyClass_protected.h)

The preferred solution, and the closest Objective-C can get to protected methods. It's just one more file, seriously, don't get your panties in a bunch over that. You can use the class extension (they are anonymous categories) and you won't lose implementation safety. It's only visible to classes that include it, which should only be subclasses; the fact that the contained methods are intended to be used as protected should be obvious to all but the most incompetent programmers because of the header name.

like image 167
Kevin Avatar answered Sep 22 '22 00:09

Kevin