ARCのプロパティ:常時またはパブリックのみ?


9

Robert McNallyによる「The Code Commandments:Best Practices for Objective-C Coding」という謙虚に名付けられた記事を2年ほど前に読んだ後、Objective-Cクラスのほとんどすべてのデータメンバーにプロパティを使用するという慣習を採用しました( 2012年5月の第3の戒め)。マクナリーはそうするためのこれらの理由をリストします(私の強調):

  1. プロパティはアクセス制限を強制します(読み取り専用など)
  2. プロパティはメモリ管理ポリシーを適用します(強い、弱い)
  3. プロパティは、カスタムセッターとゲッターを透過的に実装する機会を提供します。
  4. カスタムセッターまたはゲッターを持つプロパティを使用して、スレッドセーフティ戦略を実施できます。
  5. インスタンス変数にアクセスする単一の方法があると、コードが読みやすくなります。

私はほとんどの物件をプライベートカテゴリに分類しているので、1と4は通常、私が遭遇する問題ではありません。引数3と5はより「やわらかい」ものであり、適切なツールと他の一貫性があれば問題にならない可能性があります。最後に、私にとってこれらの議論の中で最も影響力があったのは、2番目のメモリ管理でした。それ以来、私はこれを続けています。

@property (nonatomic, strong) id object; // Properties became my friends.

最後のいくつかのプロジェクトでは、ARCを使用するように切り替えました。そのため、ほとんどすべてのプロパティを作成することは、それでも良いアイデアなのか、それとも少し不必要なのか疑問に思いました。ARCは、Objective-Cオブジェクトのメモリ管理を担当してくれます。ほとんどのstrongメンバーにとって、ivarを宣言するだけで問題なく機能します。とにかく、ARCの前後に手動で管理する必要があったCタイプであり、weakプロパティはほとんどパブリックプロパティです。

もちろん、クラスの外部からのアクセスが必要なものには、まだプロパティを使用していますが、ほとんどのプロパティはほんの一握りのプロパティであり、ほとんどのデータメンバーは、実装ヘッダーの下にivarとしてリストされています。

@implementation GTWeekViewController
{
    UILongPressGestureRecognizer *_pressRecognizer;
    GTPagingGestureRecognizer *_pagingRecognizer;
    UITapGestureRecognizer *_tapRecognizer;
}

実験として、私はこれをもう少し厳密に行っており、すべてのプロパティから離れると、いくつかの良い肯定的な副作用があります。

  1. データメンバーコードの要件(@property/ @synthesize)は、ivar宣言だけに縮小されます。
  2. 私のself.something参照のほとんどは、ちょうどにクリーンアップされました_something
  3. プライベート(ivars)とパブリック(プロパティ)のデータメンバーは簡単に区別できます。
  4. 最後に、これはAppleがプロパティを意図した目的であるように「感じている」が、それは主観的な推測である。

質問に移ります。私は徐々にダークサイドに向かっスライドしており、implementation-ivarsを優先して使用するプロパティを減らしています。すべてのプロパティを使用することに固執する必要がある理由について少し説明してください。または、必要な場合にのみivarを増やし、プロパティを減らす理由について、現在の一連の考えを確認してください。どちらか一方の最も説得力のある答えが私のマークを受け取ります。

編集:マクナリーはTwitterで、「プロパティにこだわる主な理由は、すべてを実行する1つの方法、すべてを実行する1つの方法(KVC / KVOを含む)だと思います」と言います。

回答:


5

すべてのプロパティを使用することに固執する必要がある理由について少し説明してください。または、必要な場合にのみivarを増やし、プロパティを減らす理由について、現在の一連の考えを確認してください。

今のところ、それはほとんどスタイルの問題だと言っても差し支えないと思います。あなたが言うように、プロパティのメモリ管理の利点はARCではそれほど重要ではありません。一方、直接ivarアクセス​​に戻ることの「メリット」もあまり魅力的ではありません。

  1. @property宣言は、ivar宣言に非常に似ています。@synthesizeディレクティブを回避することは大きな勝利のようには見えません-多くのコードについて話しているわけではありません。

  2. foo.something構文はかなり良くよりも間違いなくあります_something。プロパティアクセス構文は、構造体のメンバーにアクセスするためのCのドット構文のように見え、機能するように設計されています。アクセスしているオブジェクトを明示すること(selfそれが何かであるかどうかにかかわらず)は役に立ちます。(一部の人-私ではありません!- self->somethingこの理由でivarアクセス​​を提唱しています。)ivarsの主要なアンダースコア規則は問題ありませんが、すべてのObjective-Cコードで一貫して使用されていません。

  3. プロパティは、同じクラスの他のオブジェクトに格納されているデータへのアクセス( "プライベート"アクセスで許可されています)およびサブクラス(C ++の "保護された"など)によるアクセスに適しています。したがって、「プロパティ==パブリック」という考えはやや曖昧です。

  4. 私の考えでは、プロパティはメモリ管理を簡素化し、他のいくつかの利点を提供することを目的としています。あなたが言うように、メモリ管理の利点が減少すると、プロパティはあまり説得力がないように見えます。

選択したパス(内部データへの直接のivarアクセス​​に戻る)は非常に合理的な選択のようであり、コースを変更する明確な理由はありません。しかし、プロパティにこだわることも非常に合理的です。欠点はそれほど大きくなく、KVOへの準拠やより一貫したメンバーアクセススタイルなど、いくつかの優れた利点があります。

プロパティはObjective-Cの進化における最後のステップではなかったし、ARCもそうだとは思わない。具体的な情報はありませんが、ある時点で、プロパティをより魅力的なものにする、または魅力的なものにしない機能が追加される可能性は十分にあるようです。待って、何が起こるか見てみます。


1
こんにちは@Caleb、時間を割いてしっかりした記事を書いてくれてありがとう。私はKVOの側面については考えていませんでした。私は確かにAppleがこれらすべてをどこで取っているかについて非常に好奇心が強い。ARCは、一連のステップの1つとして感じられます。他の誰かがこの件について検討する気があるかどうかを確認します。それ以外の場合は、チェックマークの付いた質問を検討してください。
epologee

1
@epologeeお役に立ててうれしいです。ivarsのプラス列に追加するもう1つの項目は、デバッガーで簡単に確認できることです。プロパティが使用するivarを明示的に宣言した場合これはプロパティにも当てはまります。合成されたivarがデバッガーに表示されません。(私はいつかすぐにその変化を見ても驚くことはありません。)
カレブ

-1

私もこの質問について考えていました。私の控えめな意見では、アクセサのプロパティのみを使用すると、コードがはるかに読みやすくなります。パブリックにアクセスされる変数の意味をすぐに確認できます。個人的には、変数の前に常に@property(...)を入力すると時間がかかります。


こんにちはアレックス、SEに関する最近の質問に答えた方がいいと思います。時間のかかる議論にはあまり同意しません。時間を節約するコードを書くのではなく、将来の自分や他の誰かがそれを理解する時間を節約するコードを書きたいです。とはいえ、-1票は私の投票ではありませんでした。その人が投票を明確にするといいでしょう。
epologee 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.