[解決済み] なぜObjective-Cはプライベートメソッドをサポートしないのですか?
疑問点
でセミプライベートメソッドを宣言するための戦略をいくつか見てきました。 Objective-C で半プライベートメソッドを宣言するための戦略をいくつか見てきましたが、本当の意味でのプライベートメソッドを作る方法はないようです。 それはそれでいいんです。 しかし、なぜそうなのでしょうか? 私が本質的に受けたすべての説明は、「あなたはそれを行うことはできませんが、ここに近い近似があります」と言います。
に適用されるキーワードがいくつかあります。
ivars
(メンバー) に適用され、そのスコープを制御するキーワードがいくつかあります。
@private
,
@public
,
@protected
. なぜ、これはメソッドにもできないのでしょうか? ランタイムがサポートすべきことのように思えるのですが。 私が見逃している根本的な哲学があるのでしょうか? これは意図的なものなのでしょうか?
どのように解決するのですか?
その答えは...そう...シンプルです。 実際、シンプルさと一貫性です。
Objective-C はメソッドディスパッチの瞬間に純粋に動的です。 特に、すべてのメソッド ディスパッチは、他のすべてのメソッド ディスパッチとまったく同じ動的メソッド解決ポイントを通過します。 実行時に、すべてのメソッド実装はまったく同じ露出を持ち、メソッドとセレクタで動作するObjective-Cランタイムによって提供されるすべてのAPIは、すべてのメソッドにわたって等しく同じように動作します。
多くの人が答えているように(ここと他の質問の両方で)、コンパイル時のプライベートメソッドはサポートされています。クラスがその公に利用可能なインターフェイスでメソッドを宣言しない場合、そのメソッドはあなたのコードに関する限り存在しないのと同じかもしれません。 言い換えれば、プロジェクトを適切に編成することによって、コンパイル時に必要な可視性のさまざまな組み合わせをすべて実現することができます。
ランタイムに同じ機能を重複させるメリットはほとんどありません。 それは途方もない量の複雑さとオーバーヘッドを追加することになります。 そして、そのような複雑さがあったとしても、最もカジュアルな開発者以外のすべての人が、本来はプライベートであるはずのメソッドを実行することを防ぐことはできないでしょう。
編集: 私が気づいた前提の1つは、プライベートメッセージが プライベートなメッセージは ランタイムを通過しなければならないことです。 その結果、潜在的に大きな オーバーヘッドになる可能性があります。これは絶対に正しいのでしょうか?
はい、そうです。 クラスの実装者が、実装において Objective-C の機能セットをすべて使用したくないと考える理由はありませんし、それは動的ディスパッチが起きなければならないことを意味します。 しかし の特別なバリアントによってプライベートメソッドをディスパッチできない特別な理由はありません。
objc_msgSend()
コンパイラはそれがプライベートであることを知ることができるからです。Class
構造体にプライベートなメソッドテーブルを追加することで実現できます。プライベートな メソッドがこのチェックを回避したり 実行時間をスキップする方法はないのでしょうか?
ランタイムをスキップすることはできませんでしたが、ランタイムの はスキップしない は必ずしもプライベートメソッドのチェックを行う必要はありません。
とはいえ、サードパーティが意図的に
objc_msgSendPrivate()
を意図的に呼び出すことができない理由はありませんし、いくつかのもの (たとえば KVO) はそうしなければならないでしょう。 事実上、それは単なる慣習であり、プライベート メソッドのセレクタに接頭辞を付けたり、インターフェイス ヘッダーでそれらを言及しないことよりも実際には少しましでしょう。
しかし、そうすることは、この言語の純粋な動的性質を損なうことになります。 もはやすべてのメソッド ディスパッチが同一のディスパッチ機構を通過することはありません。 その代わりに、ほとんどのメソッドが1つの方法で動作し、ほんの一握りのメソッドが異なるという状況が残ります。
Cocoa には、Objective-C の一貫したダイナミズムの上に構築された多くのメカニズムがあるため、これはランタイムを超えて拡張されます。 たとえば、キー バリュー コーディングとキー バリュー オブザベーションの両方は、プライベート メソッドをサポートするために非常に大きく変更しなければならず、おそらく悪用可能な抜け穴を作成するか、プライベート メソッドに互換性がなくなるかのいずれかでしょう。
関連
-
[解決済み] Objective-CでNSStringsを連結するためのショートカット集
-
[解決済み] Objective-Cの定数
-
[解決済み] Objective-Cで乱数を発生させる
-
[解決済み] Objective-Cで、ある文字列が他の文字列を含んでいるかどうかを調べるにはどうすればよいですか?
-
[解決済み] Objective-Cのtypedef enumとは何ですか?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Objective-Cでデリゲートを作成するにはどうしたらいいですか?
-
[解決済み] Objective-Cで、オブジェクトの種類をテストするにはどうしたらいいですか?
-
[解決済み] 複数のサブクラスで1つのストーリーボードuiviewcontrollerを使用する方法
-
[解決済み] 別のUIViewの下にあるUIViewとのインタラクションを許可する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Objective-Cで配列に結合する
-
[解決済み] 角括弧 < > と引用符 " " を使って #import する。
-
[解決済み] Xcodeはクラッシュの原因となる行を表示しない
-
[解決済み] NSPredicate: NSDateプロパティの日によるオブジェクトのフィルタリング
-
[解決済み] ARCを使用する場合、deallocでプロパティをnilに設定するのですか?
-
[解決済み] Objective-CでNSArrayを新しいNSArrayにフィルタリングする。
-
[解決済み] Objective-Cのセレクタ?
-
[解決済み] IOSのUIViewからアプリケーションのドキュメントフォルダに画像を保存する
-
[解決済み] メソッドが存在するかどうかをチェックする
-
[解決済み] キーチェーンのアイテムは何がユニークなのか(iOSの場合)?