2011-01-29 12 views
29

外部呼び出しに対してプロパティを読み取り専用にし、内部呼び出しに対して読み取り専用にする方法を知っていますか?Objective-C:外部クラス呼び出しのためにプロパティを読み取り専用にして、自己呼び出しのためにreadwriteを作成する

私は回前の.m

@interface TheClassName() 
@property(nonatomic, retain) NSDate* theDate; 
@end 

での.h

@property(nonatomic, readonly) NSDate* theDate; 

のように思えた気にいらを読んだけど.Mをコンパイルするとき、これは警告を発生させます"TheClassNameクラス継続のプロパティtheDate属性がクラスTheClassNameプロパティと一致しません"。

とにかく、それは動作しているようです(クラスから外には読めませんが、内部から両方を行うことができます)が、警告を避けるためには少し間違っていたはずです。 これを行う良い方法がわかっている場合...

答えて

62

:あなたの.mで

@property(nonatomic, retain, readonly) NSDate* theDate; 

@interface TheClassName() 
@property(nonatomic, retain, readwrite) NSDate* theDate; 
@end 
+0

+1、それは本当に必要になるまで、 'readwrite'をデフォルトと' nonatomic'のように削除したいでしょうか? – zoul

+4

'readwrite'はあなたが望むものを正確に知っていることを明示します。一部の人々は、「いつも「非原子質」のマントラをiOSからCocoaに使用しています(私は確かにそうしています)。それはプロジェクト全体のポリシーかもしれません。 – bbum

+1

また、両方の場所で「保持」を述べなければならない理由は、「保持」対「割り当て」のゲッターの「合成」のコードジェンが異なる場合があることである。したがって、プロパティの読み込みビューでの 'retain'のポリシー*は、クラスのAPI /コントラクトの一部です。 – bbum

-2

.mで、再度@propertyを入力しないでください。しかし、どのような効果があるか分かりません。 @synthesizeを使用することを意味しましたか?

外部に読み書きされているかどうかに関わらず、theDateはクラスの実装内では読み書きが可能であることに注意してください。あなたの.hで

+1

彼はクラス拡張を使用しています。これはプライベートプロパティに使うことができ、 'self'で呼び出すことができますhttp://stackoverflow.com/questions/4464112/best-practice-for-condensing-code/4465573#4465573 – vikingosegundo

+0

これはOliver達成しようとしていますが、そうであれば、それは良い答えです。 Vikingosegundo、あなたは答えとしてそれを入れ、Oliverはそれを受け入れることができます! – Dave

+2

彼は、読み書き専用のプロパティを実現する方法を求めていますが、読み書きアクセスが可能な別のプライベートプロパティがあります。私はそのようなことをしたことはありません。私はあなたにクラス拡張を使っていると説明しましたが、質問に答えません。 – vikingosegundo

-1

プロパティを変数に裏付けされた場合、変数はクラスでデフォルトの内側から読み書き可能です。プロパティを読み取り専用にすると、設計目標が達成されます。クラス内では、self.を前もって入力せずに変数を参照してください。

+4

-1:自分自身のインスタンス変数を参照するときにもアクセサを使用する理由はたくさんあります。 (メモリ管理は1つです)Oliverの質問は有効です。 – andyvn22

3

この問題は、ARCに移行する場合にはほとんど解決されません。 2つのプロパティ宣言の代わりに、ヘッダーに宣言します。

@property(nonatomic, readonly) NSDate* theDate; 

次に、クラス拡張で、単に__strongインスタンス変数を宣言します。

@interface TheClassName() 
{ 
    __strong NSDate* _theDate; 
} 
@end 

そして今、あなたはインスタンス変数を設定することができ、実装

@implementation TheClassName 
@synthesize theDate = _theDate; 

でそれらを適切に合成します。

_theDate = [NSDate date]; 

とARCは、魔法のように強いが/変数を保持して、それを処理するために、あなたのコードに適切な保持/解除機能をインライン化します。これには、古いスタイル(保持)プロパティよりも高速で、コンパイル時にARCが保持/解放コードをインライン化するという利点があります。

+0

この場合は、ゲッターが合成されていないので、self.theDateが警告を出し、__strongは間違ってiVarを直接安全に設定することを心配する必要がないので、この場合は_Varのままにすることもできます。 – Shinohara

+0

しかし、セッターやゲッターが追加のタスク、つまりブロードキャスト通知、サニティチェックを実行したい場合はどうすればいいですか? – vikingosegundo

+0

次に、プロパティを宣言し、必要なgetterメソッドまたはsetterメソッドを記述します。__strong宣言は、setterにretain/releaseロジックを実装する必要がなくなります。 – Shinohara

関連する問題