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@interfaceshould be defined in the corresponding@implementation, and definitions of declarations in the class continuation (@interface MONClass ()) should also appear in the primary@implementation:Updated Question
Yes, that would work fine. All you should need to do is
#importthe 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…).