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?
Use Class Extension for Selective Visibility in Objective-C
Asked Answered
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.
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: #2159160 –
Wiles
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
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.
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.