7

I need to have property in class that is excluded from public framework headers, but it is available for use internally in other framework classes. What I did right now is:

MyClass.h:

@interface MyClass: NSObject

@end

MyClass+Internal.h

@interface MyClass (Internal)
@property (nonatomic, copy) NSString *mySecretProperty;
@end

MyClass.m

#import "MyClass.h"
#import "MyClass+Internal.h"

@interface MyClass ()
@property (nonatomic, copy) NSString *mySecretProperty;
@end

@implementation MyClass
@end  

And I can use private property like:

MyOtherClass.m:

#import "MyClass.h"
#import "MyClass+Internal.h"

@implementation MyOtherClass
- (void)test {
    MyClass *myClass = [MyClass new];
    NSLog(@"%@", myClass.mySecretProperty)
}
@end 

But what I don't like about this setup is that I have duplicate declaration of property in my Internal Category and inside of anonymous Category. Is there a way to improve this setup?

Mindaugas
  • 1,707
  • 13
  • 20
  • As far as it is shared between classes, it isn't a secret property anymore, is it? I can't see any way to do it without duplication... – ffarquet Sep 30 '13 at 13:41
  • well, maybe I wasn't very clear. I want it to be visible in other framework class implementations, but not visible in any public header. (in this example `MyOtherClass` is another framework class) – Mindaugas Sep 30 '13 at 13:52

1 Answers1

16

I think you could do with the class extension only, there is no need to use a category. The quick fix would be to remove the category name from the parenthesis, transforming it into the class extension, then remove the class extension declaration from the .m file. After this you only import the extension header in your framework classes and you make sure it is a private header of your framework.

MyClass.h

@interface MyClass: NSObject

@end

MyClass+Internal.h

#import "MyClass.h"

@interface MyClass ()
@property (nonatomic, copy) NSString *mySecretProperty;
@end

MyClass.m

#import "MyClass.h"
#import "MyClass+Internal.h"

@implementation MyClass
@end

MyOtherClass.m:

#import "MyClass.h"
#import "MyClass+Internal.h"

@implementation MyOtherClass
- (void)test {
    MyClass *myClass = [MyClass new];
    NSLog(@"%@", myClass.mySecretProperty)
}
@end 

The key is understanding the difference between categories and class extensions, see here: https://stackoverflow.com/a/4540582/703809

Community
  • 1
  • 1
lawicko
  • 7,246
  • 3
  • 37
  • 49
  • If MyClass+Internal.h imports MyClass.h, do you still need to import both in MyClass.m? Couldn't you only import MyClass+Internal.h? – Adam Johns Mar 07 '18 at 17:26
  • @AdamJohns No you don't actually need both in MyClass.m, but it also doesn't cost anything to have them. I always used to keep all the separate imports in my .m file for better readability. – lawicko Mar 08 '18 at 17:52