オーバーヘッドは実際の問題ではありません
最後の質問に答えると、はい、オーバーヘッドが発生しますが、特に最新のプロセッサの能力を考慮すると、もう1つのフレームをプッシュしてスタックからポップするオーバーヘッドはごくわずかです。パフォーマンスに関心がある場合は、アプリケーションのプロファイルを作成し、実際の問題がどこにあるかを判断する必要があります。いくつかのアクセサーを削除するよりも、最適化するのに適した場所が見つかることを保証します。
いいデザインだ
プライベートメンバーをカプセル化し、アクセサーとミューテーターで保護することは、優れたソフトウェア設計の基本原則にすぎません。ソフトウェアの保守、デバッグ、および拡張が容易になります。他の言語についても同じ質問をするかもしれません。たとえば、Javaクラスですべてのフィールドを公開しないのはなぜですか。(Rubyのような言語を除いて、インスタンス変数を公開することは不可能だと思います)。肝心なのは、ソフトウェアがどんどん大きくなるにつれて、真の地獄から身を守ることができるため、特定のソフトウェア設計手法が実施されているということです。
遅延読み込み
セッターでの検証は1つの可能性ですが、それ以上にできることがあります。ゲッターをオーバーライドして、遅延読み込みを実装できます。たとえば、ファイルまたはデータベースからいくつかのフィールドをロードする必要があるクラスがあるとします。従来、これは初期化時に行われます。ただし、オブジェクトをインスタンス化する人がすべてのフィールドを実際に使用するわけではない可能性があるため、代わりに、ゲッターを介して要求されるまで、それらのメンバーを初期化するのを待ちます。これにより、初期化がクリーンアップされ、処理時間をより効率的に使用できるようになります。
ARCでのサイクルの保持を回避するのに役立ちます
最後に、プロパティを使用すると、ARCでブロックを使用したループの保持を簡単に回避できます。ivarsの問題は、それらにアクセスするときに、暗黙的に自分自身を参照していることです。だから、あなたが言うとき:
_foo = 7;
あなたが本当に言っているのは
self->_foo = 7;
したがって、次のようになります。
[self doSomethingWithABlock:^{
_foo = 7;
}];
これで、保持サイクルができました。必要なのは弱いポインタです。
__block __weak id weakSelf = self;
[self doSomethingWithABlock:^{
weakSelf->_foo = 7;
}];
さて、これは明らかにセッターとゲッターの問題ですが、明示的にself.propertyを呼び出す必要があるため、weakSelfの使用を忘れる可能性は低くなりますが、ivarは暗黙的にselfによって参照されます。プロパティを使用している場合、静的アナライザーはこの問題を解決するのに役立ちます。