2

同じ名前のメソッドで2つのクラスを作成しました。それらの1つではプライベート、もう1つではパブリックです。次に、コードのどこかにこれを書きます:

-(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 ファイルのクラス拡張でメソッドを宣言しているときは、パブリック ヘッダー ファイルで公開されないように隠しているだけです。あなたが今していることは、ヘッダー ファイルからメソッドを隠しているため、優れた設計と見なされます。

基本的に、私が従う規則は、できる限り public ヘッダーに入れないようにし、それ以外はすべてクラス拡張に入れることです。今のところ本当にできることはこれだけです。

于 2012-04-25T20:26:26.873 に答える
-1

.h ファイルでメソッドを宣言すると public になります。プライベートな可視性が必要な場合は、.m でメソッドを宣言する必要があります。次に例を示します。

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

@implementation ClassB

//Rest of .m
于 2012-04-25T20:03:06.790 に答える