Pregunta

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
¿Fue útil?

Solución

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…).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top