Use Class Extension for Selective Visibility in Objective-C
Asked Answered
L

2

9

Would it make any sense to put class extensions in their own .h files and #import them selectively to get various levels of visibility for a class' methods and properties? If this is a bad idea (or would not work), why?

Linus answered 18/8, 2011 at 16:4 Comment(0)
W
15

It is a great idea and exactly why Class Extensions were designed (and why they are different than categories).

Namely, you can:

Foo.h

@interface Foo:NSObject
...public API here...
@property(readonly, copy) NSString *name;
@end

Foo_FrameworkOnly.h

@interface Foo()
@property(readwrite, copy) NSString *name;
@end

Foo.m

#import "Foo.h"
#import "Foo_FrameworkOnly.h"

@interface Foo()
... truly implementation private gunk, including properties go here ...
@end

@implementation Foo
@synthesize name = name_;
@end

And effectively have a property that is publicly readonly and privately read write for only the implementation files that import Foo_FrameworkOnly.h.

Wiles answered 18/8, 2011 at 16:38 Comment(7)
Thanks @bbum, that's great... your example gives you public, package (or whatever) and private, which is pretty much all I've ever hoped for. Personally, I think it's horrendous to do this at the file level, but that's the price of being this close to the metal, I guess.Linus
There is a tremendous amount of complexity incurred by supporting private API at other than the file level and, especially in a purely dynamic language like Objective-C, "private" is effectively meaningless anyway (i.e. the compiler can't compile away or entirely obfuscate "private" symbols).Wiles
(I'm not disagreeing -- just saying the there is a significant cost) You might find this interesting, too: #2159160Wiles
you mean tremendous complexity for the Runtime (and perhaps compiler). Thanks for the link, it does help flesh out the discussion.Linus
Yup; both Runtime and compiler, definitely.Wiles
my point was that we have complexity for the average developer in lieu of complexity in the runtime and compiler. I miss visibility keywords in C#, Java and even ActionScript. But I digress.Linus
This example is extremely useful for framework developers who want to have more fine-grained control on class interface visibility.Benedicite
A
-2

Class extension (as opposed to subclassing) in Objective-C is accomplished with Categories. In Xcode, go to File > New > File and select Objective-C Category. It will ask you what to call the category and what class it should extend. You'll get a .h/.m pair in which to put your interface and implementation, respectively. If you want access to the features provided in your extension, just import its .h file.

Agamete answered 18/8, 2011 at 16:31 Comment(4)
Categories and Extensions are similar, but they are not the same. "Class extensions are like anonymous categories, except that the methods they declare must be implemented in the main @implementation block for the corresponding class."Inspiratory
@albertamg, theoretically, if the .m doesn't import the .h containing the class extension, then it doesn't have to implement it, right?Linus
@Yar Well, the compiler won't complain about the implementation being incomplete if the class extension is not imported into the .m file.Inspiratory
Downvote was mine; class extensions are not categories and vice-versa. They are quite thoroughly different things (extensions cannot have implementations, categories cannot influence property synthesis, for example). And, yes, if an extension isn't imported, the compiler won't know that an implementation is required (categories also behave differently; a category does not have to have a corresponding @implementation at all).Wiles

© 2022 - 2024 — McMap. All rights reserved.