1. ホーム
  2. objective-c

[解決済み] NSInvocation for Dummies?

2022-05-17 14:37:25

質問

具体的にどのように NSInvocation はどのように機能するのでしょうか?良い紹介はありますか?

私は特に、次のコード(から)がどのように理解されるかについて問題を抱えています。 Mac OS X 用 Cocoa プログラミング第 3 版

) がどのように機能するかを理解し、チュートリアルのサンプルとは別にその概念を適用することができるようにしたいのです。そのコードとは

- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index
{
    NSLog(@"adding %@ to %@", p, employees);
    // Add inverse of this operation to undo stack
    NSUndoManager *undo = [self undoManager];
    [[undo prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];
    if (![undo isUndoing])
        [undo setActionName:@"Insert Person"];

    // Finally, add person to the array
    [employees insertObject:p atIndex:index];
}

- (void)removeObjectFromEmployeesAtIndex:(int)index
{
    Person *p = [employees objectAtIndex:index];
    NSLog(@"removing %@ from %@", p, employees);
    // Add inverse of this operation to undo stack
    NSUndoManager *undo = [self undoManager];
    [[undo prepareWithInvocationTarget:self] insertObject:p
                                       inEmployeesAtIndex:index];
    if (![undo isUndoing])
        [undo setActionName:@"Delete Person"];

    // Finally, remove person from array
    [employees removeObjectAtIndex:index];
}

やろうとしてることはわかるんだけどね。(ちなみに employeesNSArray のカスタム Person クラスのようなものです)。

.NETの人なので、よくわからないObj-CやCocoaの概念を、おおよそ類似の.NETの概念に関連付けようとします。これは、.NETのデリゲート概念に似ていますが、型付けされていないのでしょうか?

これは本から100%明確ではないので、私は本当のCocoa/Obj-Cの専門家から補足的な何かを探しています、再び私が単純な(-っぽい)例の下の基本概念を理解するという目標で。第9章までは、自分で応用できるようになりたいと思っています。でも今は......。

ありがとうございました。

どのように解決するのですか?

によると Apple の NSInvocation クラスリファレンスによると :

NSInvocation は静的にレンダリングされたObjective-Cのメッセージで、つまり、アクションがオブジェクトになったものです。

で、その中に 少し をもっと詳しく説明します。

メッセージの概念は、objective-cの哲学の中心です。メソッドを呼び出したり、あるオブジェクトの変数にアクセスしたりするときはいつでも、そのオブジェクトにメッセージを送っていることになります。 NSInvocation は、異なる時点でオブジェクトにメッセージを送りたいときや、同じメッセージを何度も送りたいときに便利です。 NSInvocation を使うと を記述します。 を記述し、次に を呼び出す を呼び出す(実際にターゲットオブジェクトに送信する)。


例えば、配列に文字列を追加したい場合を考えてみましょう。通常であれば addObject: というメッセージを送ります。

[myArray addObject:myString];


では、例えば NSInvocation を使用して、このメッセージを他のある時点で送信したいとします。

まず NSInvocation オブジェクトを用意します。 NSMutableArray 's addObject: セレクタを使用します。

NSMethodSignature * mySignature = [NSMutableArray
    instanceMethodSignatureForSelector:@selector(addObject:)];
NSInvocation * myInvocation = [NSInvocation
    invocationWithMethodSignature:mySignature];

次に、どのオブジェクトにメッセージを送るかを指定します。

[myInvocation setTarget:myArray];

そのオブジェクトに送りたいメッセージを指定します。

[myInvocation setSelector:@selector(addObject:)];

そして、そのメソッドの引数を記入します。

[myInvocation setArgument:&myString atIndex:2];

オブジェクトの引数はポインタで渡さなければならないことに注意してください。ありがとうございました。 ライアン・マッケイグ が指摘してくれたことに感謝します。 Apple のドキュメント をご覧ください。

この時点では myInvocation は完全なオブジェクトであり、送信可能なメッセージを記述しています。実際にメッセージを送信するには、呼び出すことになります。

[myInvocation invoke];

この最後のステップでは、メッセージを送信するために、本質的に実行される [myArray addObject:myString]; .

電子メールを送るようなものだと考えてください。新しいメールを開くと ( NSInvocation オブジェクト) を開き、送信したい相手 (オブジェクト) のアドレスを記入し、受信者用のメッセージを入力します (指定するのは selector と引数を指定する)、そして、"send" をクリックします(コール invoke ).

参照 NSInvocationの使用 を参照してください。 参照 NSInvocation の使用法 を参照してください。


NSUndoManager 用途 NSInvocation オブジェクトを使用することで コマンドを使用することができます。基本的に、あなたが行っているのは NSInvocation オブジェクトを作成し、次のように述べています。あなたは NSInvocation オブジェクトに NSUndoManager に追加し、そのオブジェクトを取り消し可能なアクションの配列に追加します。ユーザーが "Undo" を呼び出した場合。 NSUndoManager は単に配列の中で最も新しいアクションを探し、保存されている NSInvocation オブジェクトを呼び出して必要なアクションを実行します。

参照 Undo操作の登録 をご覧ください。