objective-c中的私有方法不是私有的

时间:2012-04-25 19:53:10

标签: objective-c private encapsulation

我创建了两个具有相同名称的方法的类。其中一个是私人的,另一个是公共的。 然后我在代码的某个地方写下这个:

-(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];
}

在控制台中我看到了这个: 2012-04-25 23:41:28.183 testmagic [558:403] classB - doSmth

这是课程的来源:

//.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

我知道,这是因为Obj-C中方法的“消息”性质,并且在运行时类可能不知道它的哪个方法是私有的还是公共的,但这里是问题:

我如何制作真正私密的方法?我听说通过反编译可以看到方法名称,所以有人可以使用我的私有API。我该如何预防?

4 个答案:

答案 0 :(得分:2)

运行时无法调用它从未知道的内容。我通常采用的方法是使用static函数:

<强> 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

答案 1 :(得分:1)

解决您的问题的方法可能是使用proxy /façade类,该类在内部聚合您的私有类的实例。 E.g:

// .h
@interface FoobarFacade: NSObject
- (void)publicMethod;
@end

// .m
@interface FoobarFacade ()
{
    Foobar* impl;
}
@end

@interface Foobar: NSObject
- (void)secretMethod;
@end

@implementation Foobar
- (void)secretMethod { NSLog(@"foobar secret method"); }
@end

@implementation FoobarFacade
- (void)publicMethod {
     NSLog(@"façade public method");
     [impl secretMethod];    // calling into the secret method
}
@end

当然这也不是100%安全,运行时没有像其他人已经说过的那样设置障碍。

答案 2 :(得分:0)

现在你不能拥有真正的私人方法。当你在.m文件中的类扩展中声明一个方法时,你只是将它隐藏在公共头文件中。你现在正在做的事情被认为是好的设计,因为你从头文件中隐藏了这个方法,这意味着人们必须花一些时间来找到那些隐藏的方法,但是他们仍然可以找到它们。

基本上我遵循的规则是尽可能少地将其放入公共标题中,并将其他所有内容放入类扩展中。这就是你现在真正能做的一切。

答案 3 :(得分:-1)

如果声明.h文件中的方法是公共的。如果您想要隐私可见性,则必须在.m中声明方法,例如:

@interface ClassB (Private_Methods)
- (void)doSmth;
@end

@implementation ClassB

//Rest of .m