Search code examples
objective-cprivateencapsulation

Private methods in objective-c not private


I've created two classes with methods with same name. In one of them it is private, in another - public. Then somewhere on code i write this:

-(void) doMagic:(id) object {
    [(ClassA*)object doSmth];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    ClassB * objB = [[ClassB alloc] init];
    [self doMagic:objB];
}

In console i see this: 2012-04-25 23:41:28.183 testmagic[558:403] classB - doSmth

Here's classes' sources:

//.h
@interface ClassA : NSObject
-(void) doSmth;
@end
//.m
@implementation ClassA
-(void)doSmth {
    NSLog(@"classA - doSmth");
}
@end

//.h
@interface ClassB : NSObject


@end
//.m
@interface ClassB ()
-(void) doSmth;

@end;

@implementation ClassB
- (void)doSmth {
    NSLog(@"classB - doSmth");
}
@end

I know, it's because of "message" nature of methods in Obj-C, and at runtime class possibly do not know which of it's methods are private or public, but here's the question:

How can i make really private method? I heard that with decompiling it's possible to see methods names, so someone can just use my private API. How can i prevent it?


Solution

  • The runtime cannot call what it never knows about. The approach I typically take is to use a static function:

    MONObject.h

    @interface MONObject : NSObject
    // ...
    @end
    

    MONObject.m

    // 'private' methods and ivars are also visible here
    @interface MONObject()
    // ...
    @end
    
    // typically here:
    static void fn(MONObject * const self) {
        NSLog(@"%@", [self description]);
    }
    
    @implementation MONObject
    // ...
    
    // sometimes here:
    static void fn2(MONObject * const self) {
        NSLog(@"%@", [self description]);
    }
    
    @end