質問
愚かな質問ですが、なぜ財産を宣言するときに「保持」する必要があるのですか?それが何かを割り当てられたとき、それはとにかく保持されませんか?
この例を見ると、オブジェクトはAlloc'edのときに自動的に保持されるように思われますが、ポイントは何ですか?
#import "Fraction.h"
#import <stdio.h>
int main( int argc, const char *argv[] ) {
Fraction *frac1 = [[Fraction alloc] init];
Fraction *frac2 = [[Fraction alloc] init];
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// increment them
[frac1 retain]; // 2
[frac1 retain]; // 3
[frac2 retain]; // 2
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// decrement
[frac1 release]; // 2
[frac2 release]; // 1
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// release them until they dealloc themselves
[frac1 release]; // 1
[frac1 release]; // 0
[frac2 release]; // 0
■出力
分数1はカウントを保持します:1
フラクション2はカウントを保持します:1
分数1を保持カウント:3
フラクション2はカウントを保持します:2
分数1を保持カウント:2
フラクション2はカウントを保持します:1
取引率
取引率
これは私を夢中にさせています!
解決
プロパティのデフォルトの動作は、保持されるのではなく、割り当てられます。これらは同じ動作ではありません。あなたのプロパティがINTなどのプリミティブデータ型用である場合、割り当ては使用が正しいでしょう。ただし、指定(保持)を指定し、プロパティがnsobject *オブジェクトなどのオブジェクトポインターをポイントすると、ポインターにオブジェクトのメモリアドレスが割り当てられ、保持カウントが1つに増分されます。あなたのプログラムが唯一の主な機能に過ぎない場合、それは目的を見るのが難しいです。ただし、クラスにこの方法があるとします。
-(void)setMyArrayWithString:(NSString *)s{
myArray = [NSArray arrayWithObject:s];
}
MyArrayがNSARRAY *MyArrayとして定義され、適切な@Property(保持)ステートメントを持っているとします。メソッドが戻るまですべてが正常に機能します。これは、NSARRAYから返されたオブジェクトが自動化されたオブジェクトであるためです。保持しないと、NSautoreLeasepoolによってリリースされ、使用することはできません(そして、厄介なバグと悪いアクセス違反が得られます)。これを修正するために、2つのことのいずれかを実行できます。
-(void)setMyArrayWithString:(NSString *)s{
self.myArray = [NSArray arrayWithObject:s];
// OR
myArray = [[NSArray arrayWithObject:s] retain];
}
最初のソリューションは、self.myarrayを使用して@property定義を利用します。このコードは、機能が返されたときにそれを失わないようにオブジェクトを割り当てて保持します。 2番目のソリューションは、nsarray *myarrayポインターを手動で設定し、NSARRAYオブジェクトを手動で保持します。いずれにせよ、nsautoreleasepoolは関数の最後にオブジェクトをリリースしますが、以前の維持から保持されているため、それは扱われません。