This is what I have in my implementation file for one of my classes...
Code Setup #1
@interface MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod;
@end
@implementation MyViewController
- (void)viewDidLoad
{
NSString *myString = [self myPrivateMethod];
NSLog(@"%@", myString);
}
- (NSString *)myPrivateMethod
{
return @"someString";
}
@end
With this code, everything works and it logs "someString".
But shouldn't my code look differently somehow? I actually am using that category by accident (I had copy/pasted something and didn't notice "PrivateMethods" was there; I meant to be using a class extension).
Shouldn't my code actually look like one of the following:
Code Setup #2
@interface MyViewController ()
- (NSString *)myPrivateMethod;
@end
@implementation MyViewController
....
Or:
Code Setup #3
@interface MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod;
@end
@implementation MyViewController (PrivateMethods)
....
What are the nuances behind what is happening in this situation? How is Code Setup #1 different from Code Setup #2?
Edit: Question about Setup #3
What does setting it up like this accomplish? Would this even "work"?
@interface MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod;
@end
@implementation MyViewController
- (void)viewDidLoad
{
NSString *myString = [self myPrivateMethod];
NSLog(@"%@", myString);
}
@end
@implementation MyViewController (PrivateMethods)
- (NSString *)myPrivateMethod
{
return @"someString";
}
@end
the selectors just get pushed into the same flat namespace at runtime. the compiler adds no additional code to distinguish that the selector is a method defined in a category (when messaging) --it's all flat.
the categories' symbols are exported differently, but that does not really matter to the runtime once loaded.
you should generally use Setup #3: if a method is declared in a category, it should be defined in the category's @implementation
. the compiler will save you occasionally and it is a purer structure. (of course, not every method belongs in a category). Similarly, the declarations in the @interface
should be defined in the corresponding @implementation
, and definitions of declarations in the class continuation (@interface MONClass ()
) should also appear in the primary @implementation
:
@implementation MONClass
// add your @interface MONClass definitions here
// also add your @interface MONClass () definitions here
@end
Updated Question
Yes, that would work fine. All you should need to do is #import
the header which contains @interface MyViewController (PrivateMethods)
. I actually do this in some classes to categorize/organize by topic.
Typically, "Private Methods" are declared in the class continuation, but it is not necessary to do so (ivars/properties OTOH…).