2012-01-18 5 views
0

私はこのコードを持っていると仮定し...iphone - プロパティとインスタンス変数

がfoo.h

@interface Foo : NSObject { 
    NSString *aString; // 1 
} 

@property (nonatomic, retain) NSString *aString; 

foo.m

@synthesize aString = _aString; 


.... 

- (void)dealloc { 
    [aString release]; 
    [super dealloc]; 
} 

は私の質問は以下のとおりです。

  • 本当に "1"でaStringを宣言する必要がありますか? (コードを参照)
  • 私はaString = _aStringを合成していますが、すでにインスタンス変数 を作成していますか?
  • foo.h(@property)のプロパティを保持している場合、deallocでaStringを解放するとXcodeがなぜ苦情を言いますか?

ありがとう。

答えて

3

プロパティとバッキング変数が混在しています。 "aString"はプロパティで、メソッド呼び出しでアクセスします([self aString]など)。 「_aString」はバッキング変数で、直接アクセスします(例:_aString)。

ためにあなたの質問を取る:あなたは変数として_aStringを使用するようにコンパイラに告げたので

  • 号には、これは、未使用の変数です。 (あなたは実際に現代のランタイムでどちらかを宣言する必要はありません)

  • はい、私の最初の質問への答えに示されています。

  • コンパイラはオブジェクトにメッセージを送信することを期待しており、 "aString"は記述されていないため定義されていないためです。通常、[self aString]を使用してオブジェクトにアクセスしますが、これは特殊なケースです:-deallocと-initXYZでは、潜在的な副作用のためにアクセサメソッドを使用しません。 [_aString release]に切り替えると、すべてが機能します(ARCがない場合は、まったく解放しません)。

+0

ああ、わかるよ、文字列は本物のエイリアスの一種だ...:D ...ありがとう。あなたの答えは完璧だった!!!!!! – SpaceDog

+0

コンパイラは、あなたのためにいくつかのことをバックグラウンドで実行しています。私は詳細な応答を書いた(http://www.cocoabuilder.com/archive/cocoa/312413-code-error-in-your-first-mac-app-tutorial.html#312424)誰かのためのココア開発者あなたがプロパティをよりよく理解したい場合は、メーリングリストをしばらくお待ちください。 –

0

@synthesizeには、インスタンス変数( "1")がNSString* _aStringである必要があります。

異なる名前の変数を使用して合成する理由は、aStringを直接変更して誤ってポインタを上書きするのではなく、常に古いオブジェクトを適切に解放するためにself.aStringを使用するためです。

ARCを有効にしていますか?もしそうなら、そういうわけで、Xcodeはそれをリリースすることを訴えるのです。

+0

いいえこれはiOS 4.2を対象としたプロジェクトです"1"の_aStringの宣言に関しては論理的ですが、なぜ多くの著者がそれをしないのでしょうか?私はその人が@propertyで宣言して合成するプロジェクトをたくさん見てきました。 – SpaceDog

-1

回答: -

私は実際には "1" でaStringのを宣言する必要がありますか? (コードを参照) - 今度はiOS 4以降で宣言する必要はありません。

私はaString = _aStringを合成していますが、すでにインスタンス変数を作成しています。 - はい

foo.h(@property)のプロパティを保持している場合、なぜdeallocでaStringを解放するとXcodeがエラーになるのですか? - これを使う必要があります - self.aString = nil、これは気をつけます。順序であなたの質問に答えるために

+1

間違った答えです。 –

+0

deallocやinitでアクセサーを使用しないでください –

+0

なぜdownvoteは、アップルのObjective-C 2.0で同じことが言及されていますが、p74 - なぜあなたは、現代のランタイムを使用してインスタンス変数を合成していますが、インスタンスにアクセスすることはできませんvar直接アクセスできるので、アクセサーメソッドを呼び出す必要があります。あなたはこれをチェックして、どこが間違っているか教えてください。 – rishi

0

  • 号があり、私が欠けている「ベスト・プラクティス」の理由のいくつかの並べ替えは、かもしれませんが、@propertyは同様にインスタンス変数を合成します。
  • を宣言するときは、_aStringを呼び出して合成ゲッター/セッターにアクセスせずに_aStringを直接操作するか、合成ゲッター/セッター(self.aStringを呼び出して)を使用します。
  • 他の誰かがそれを解放している可能性があります。他の誰かがそれを解放しているか、ARCを使用している可能性があります。 NSStrings(およびその他の単純なオブジェクトでは、ディープコピーメソッドをすぐに利用できます)を使用すると、@property (copy)_aString = [stringPassedToInit copy]を使用するのが最も適していることがわかります。 ARCを使用している場合、ほとんどの場合、保持/解放を心配する必要はありません。
0

いいえ、私は思っていたので、これ以上ivarsを宣言する必要はありません。インタフェース宣言の{...}部分全体を削除することはできますが、それは何の違いもありません。

あなたのivarの名前がaStringではなく、_aStringであることから、不満を言います。代わりに、

[_aString release] 

と言う必要があります。

+0

いいえ、私はARCを使用していません。あなたは、象牙を宣言する必要はないのですか?私が宣言しなければならない他のイヴァール... – SpaceDog

+0

はい、あなたがプロパティを合成する場合、それのためにivarを宣言する必要はありません。すべてのプロパティを使用することができ、イーバールはまったく使用しないことがベストプラクティスです。プロパティをプライベートにする場合は、.hファイルではなく.mファイル内のプライベートインターフェイス内に宣言します。 –

-1

私の答えは以下のとおりです。

  • NO
  • YES
  • ではなく[_string release]を試してみてください。
関連する問題