1. ホーム
  2. objective-c

[解決済み] なぜObjective-Cはプライベートメソッドをサポートしないのですか?

2022-08-14 11:24:46

疑問点

でセミプライベートメソッドを宣言するための戦略をいくつか見てきました。 Objective-C で半プライベートメソッドを宣言するための戦略をいくつか見てきましたが、本当の意味でのプライベートメソッドを作る方法はないようです。 それはそれでいいんです。 しかし、なぜそうなのでしょうか? 私が本質的に受けたすべての説明は、「あなたはそれを行うことはできませんが、ここに近い近似があります」と言います。

に適用されるキーワードがいくつかあります。 ivars (メンバー) に適用され、そのスコープを制御するキーワードがいくつかあります。 @private , @public , @protected . なぜ、これはメソッドにもできないのでしょうか? ランタイムがサポートすべきことのように思えるのですが。 私が見逃している根本的な哲学があるのでしょうか? これは意図的なものなのでしょうか?

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

その答えは...そう...シンプルです。 実際、シンプルさと一貫性です。

Objective-C はメソッドディスパッチの瞬間に純粋に動的です。 特に、すべてのメソッド ディスパッチは、他のすべてのメソッド ディスパッチとまったく同じ動的メソッド解決ポイントを通過します。 実行時に、すべてのメソッド実装はまったく同じ露出を持ち、メソッドとセレクタで動作するObjective-Cランタイムによって提供されるすべてのAPIは、すべてのメソッドにわたって等しく同じように動作します。

多くの人が答えているように(ここと他の質問の両方で)、コンパイル時のプライベートメソッドはサポートされています。クラスがその公に利用可能なインターフェイスでメソッドを宣言しない場合、そのメソッドはあなたのコードに関する限り存在しないのと同じかもしれません。 言い換えれば、プロジェクトを適切に編成することによって、コンパイル時に必要な可視性のさまざまな組み合わせをすべて実現することができます。

ランタイムに同じ機能を重複させるメリットはほとんどありません。 それは途方もない量の複雑さとオーバーヘッドを追加することになります。 そして、そのような複雑さがあったとしても、最もカジュアルな開発者以外のすべての人が、本来はプライベートであるはずのメソッドを実行することを防ぐことはできないでしょう。

編集: 私が気づいた前提の1つは、プライベートメッセージが プライベートなメッセージは ランタイムを通過しなければならないことです。 その結果、潜在的に大きな オーバーヘッドになる可能性があります。これは絶対に正しいのでしょうか?

はい、そうです。 クラスの実装者が、実装において Objective-C の機能セットをすべて使用したくないと考える理由はありませんし、それは動的ディスパッチが起きなければならないことを意味します。 しかし の特別なバリアントによってプライベートメソッドをディスパッチできない特別な理由はありません。 objc_msgSend() コンパイラはそれがプライベートであることを知ることができるからです。 Class 構造体にプライベートなメソッドテーブルを追加することで実現できます。

プライベートな メソッドがこのチェックを回避したり 実行時間をスキップする方法はないのでしょうか?

ランタイムをスキップすることはできませんでしたが、ランタイムの はスキップしない は必ずしもプライベートメソッドのチェックを行う必要はありません。

とはいえ、サードパーティが意図的に objc_msgSendPrivate() を意図的に呼び出すことができない理由はありませんし、いくつかのもの (たとえば KVO) はそうしなければならないでしょう。 事実上、それは単なる慣習であり、プライベート メソッドのセレクタに接頭辞を付けたり、インターフェイス ヘッダーでそれらを言及しないことよりも実際には少しましでしょう。

しかし、そうすることは、この言語の純粋な動的性質を損なうことになります。 もはやすべてのメソッド ディスパッチが同一のディスパッチ機構を通過することはありません。 その代わりに、ほとんどのメソッドが1つの方法で動作し、ほんの一握りのメソッドが異なるという状況が残ります。

Cocoa には、Objective-C の一貫したダイナミズムの上に構築された多くのメカニズムがあるため、これはランタイムを超えて拡張されます。 たとえば、キー バリュー コーディングとキー バリュー オブザベーションの両方は、プライベート メソッドをサポートするために非常に大きく変更しなければならず、おそらく悪用可能な抜け穴を作成するか、プライベート メソッドに互換性がなくなるかのいずれかでしょう。