2

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

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

4 回答 4

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
于 2012-04-25T20:23:13.223 回答
1

解决您的问题的方法可能是使用代理/外观类,该类在内部聚合您的私有类的实例。例如:

// .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% 安全的,运行时没有其他人已经说过的障碍。

于 2012-04-25T20:44:14.687 回答
0

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

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

于 2012-04-25T20:26:26.873 回答
-1

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

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

@implementation ClassB

//Rest of .m
于 2012-04-25T20:03:06.790 回答