これは、ivar の代わりにプロパティを解放しているからでない限り、わかりません。誰かが問題に光を当てることができますか?
self.dataToBeLoaded = [[NSMutableData alloc] initWithLength:10000];
[self.dataToBeLoaded release];
警告はIncorrect decrement of the reference count of an object that is not owned by the caller
です。
プロパティには、そのdataToBeLoaded
セッターに関連付けられた保持属性があります。
私の理解では、alloc init は保持カウントをインクリメントし、プロパティの割り当ては保持カウントをインクリメントします。一度しか持たないので、配属後すぐに解放する。
更新 -- いくつかの実験結果:
以下のコメントで、retain プロパティが合成されたセッターに何をするかについて矛盾したアドバイスを受け取ったことを指摘したので、上記のコードをいくつかのロギングで変更して、少し実験してみようと思いました。
NSLog(@"retain 1 = %d", [dataToBeLoaded_ retainCount]);
self.dataToBeLoaded = [[NSMutableData alloc] initWithLength:10000];
NSLog(@"retain 2 = %d", [dataToBeLoaded_ retainCount]);
[self.dataToBeLoaded release];
NSLog(@"retain 3 = %d", [dataToBeLoaded_ retainCount]);
各ログ ステートメントでの結果は、0、2、および 1 でした。
どうやら、alloc または init コードにステップ インして保持カウントが 0 から 1、2 に変化するのを確認することはできないようです。NSMutableData クラスをサブクラス化することもできましたが、時間が足りませんでした。
保持カウント プロパティの値に依存することはできないとよく言われますが、私が得た情報は一貫しているように見え、例に示すようなコードの短い範囲で妥当な動作を期待できます。したがって、以前のアドバイスが正しいと信じる傾向があります。retain プロパティは、セッター内に保持を含めるという約束です。したがって、ここでは、alloc/init からの保持と、setter への呼び出しからの保持があります。したがって、保持カウントは 2 に設定されます。
このコードを実行すると:
NSMutableData *theData;
NSLog(@"retain 1 = %d", [theData retainCount]);
theData= [[NSMutableData alloc] initWithLength:10000];
NSLog(@"retain 1a = %d", [theData retainCount]);
self.dataToBeLoaded = theData;
NSLog(@"retain 2 = %d", [theData retainCount]);
[self.dataToBeLoaded release];
NSLog(@"retain 3 = %d", [theData retainCount]);
各ログ ステートメントでの保持カウントは、0、1、2、1 です。
したがって、セッターがretain
. これは実際に起こっているため、ヒントというよりも約束のように見えます。
私は他の説明を受け入れます。私はこれについて傲慢になりたくありません。何が起こっているのかを正しく理解したいだけです。(この質問の件名の)警告は本当に偽りであり、心配する必要はないようです。
もう 1 つの実験は、@property ステートメントの属性としてassign
ではなく、使用して行われます。retain
同じコードで:
NSMutableData *theData;
NSLog(@"retain 1 = %d", [theData retainCount]);
theData= [[NSMutableData alloc] initWithLength:10000];
NSLog(@"retain 1a = %d", [theData retainCount]);
self.dataToBeLoaded = theData;
NSLog(@"retain 2 = %d", [theData retainCount]);
[self.dataToBeLoaded release];
NSLog(@"retain 3 = %d", [theData retainCount]);
各ログの保持カウントは 0、1、1 (setter が保持しなかった) であり、エラー メッセージ: message sent to deallocated instance
. 前回のリリースでは保持カウントがゼロに設定されていたため、割り当て解除がトリガーされました。
更新 2
最後の更新 -- 合成されたセッターが独自のコードでオーバーライドされると、セッターに明示的に含めない限り、retain 属性は監視されなくなります。どうやら (これは、ここの他のスレッドで私が言われたことと矛盾しています)、それが必要な場合は、セッターに独自の保持を含める必要があります。ここではテストしませんでしたが、おそらく最初に古いインスタンスをリリースする必要があります。そうしないと、リークされてしまいます。
このカスタム セッターには、 @propety 宣言のプロパティ属性がなくなりました。
- (void) setDataToBeLoaded:(NSMutableData *)dataToBeLoaded {
dataToBeLoaded_ = dataToBeLoaded;
}
意味あり。合成されたセッターをオーバーライドすると、宣言されたすべてのプロパティがオーバーライドされます。合成されたセッターを使用すると、宣言されたプロパティが合成された実装で観察されます。
@property 属性は、合成されたセッターの実装方法に関する「約束」を表します。カスタム セッターを作成したら、あとは独力です。