2

私は奇妙な問題に直面しています。これは非常に一般的で、多くのサイトで発生する可能性がありますが、これは少し奇妙です。私は可変配列オブジェクト使用オブジェクトを割り当ててから、私が行ったように解放し、オブジェクトの割り当てと解放のたびに行っています。リリース行にコメントを付けて nil を使用すると、正常に動作します。以下は私のコードです。ご覧になり、より良い方法を提案してください。

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    NSMutableArray * array = [[NSMutableArray alloc] init];
    array= [[dbSingleton sharedInstance] getAll_Players];
    NSMutableDictionary * dict = [array objectAtIndex:row];
    NSString * autoID = [dict objectForKey:@"autoId"];
    NSLog(@"%@",[NSString stringWithFormat:@"%@ %@",[dict valueForKey:@"fName"],[dict valueForKey:@"lName"]]);
    [array release];
}

これは非常に一般的であり、人々はこれらの質問をするのが好きではないので、私のポイントを減らさないでください. 前もって感謝します。

4

2 に答える 2

3

アレイを割り当て初期化して解放する必要はありません。

同じ内容の新しい配列は必要ないと思いますが、sharedInstance 配列の参照のみが必要です。

そのために、これらの行を削除し、配列のみを宣言します。

 NSMutableArray *array = [[dbSingleton sharedInstance] getAll_Players];

ここでは配列を割り当て初期化していないため、同じものを解放する必要はありません。したがって、メモリに関する懸念は必要ありません。

最大の場合、参照カウントを減らすためにできることは、参照が完了したらすぐにその参照を無効にすることです。

    NSMutableArray * array= [[dbSingleton sharedInstance] getAll_Players];
    NSMutableDictionary * dict = [array objectAtIndex:row];
    NSString * autoID = [dict objectForKey:@"autoId"];
    NSLog(@"%@",[NSString stringWithFormat:@"%@ %@",[dict valueForKey:@"fName"],[dict valueForKey:@"lName"]]);
    array = nil;  // not mandatory, it will work without this line as well

この方法は、ARCまたはARC の両方で機能します。

お役に立てれば。

于 2013-09-03T07:50:58.423 に答える
2

まず、配列変数を初期化します

NSMutableArray * array = [[NSMutableArray alloc] init];

そして、この時点で正しく、この変数をある時点で解放する必要があります。しかし、あなたが書くとき

array= [[dbSingleton sharedInstance] getAll_Players];

割り当てたばかりの配列変数を上書きします。getAll_Players から取得した配列に対しても保持を呼び出さない限り、配列はここで解放する必要はありません。

この問題を修正するには、次のようにする必要があります。

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSMutableArray * array = [[dbSingleton sharedInstance] getAll_Players];
NSMutableDictionary * dict = [array objectAtIndex:row];
NSString * autoID = [dict objectForKey:@"autoId"];
NSLog(@"%@",[NSString stringWithFormat:@"%@ %@",[dict valueForKey:@"fName"],[dict valueForKey:@"lName"]]);
}

編集:(コメントの質問への回答として)

NSMutableArray * array = [[dbSingleton sharedInstance] getAll_Players];  

上記の行は、変数「array」を、「[[dbSingleton sharedInstance] getAll_Players]」が返すものへのポインタとして設定するだけです。その行では参照カウントは増加も減少もしないため、減少もすべきではありません。(そして、オブジェクトが期待したときに常に解放されるとは限らないため、オブジェクトの保持カウント値を決して信頼しないでください)。

オブジェクトの作成時にallocnewcopy、およびmutableCopyを呼び出し、 retain on および object を呼び出した場合にのみ参照カウントが増加し、これらのキーワードを自分で使用した場合にのみ、オブジェクトを解放または自動解放する必要があります。このキーワードによって RF カウントが増加することに注意してください。releaseとautoreleaseは RF カウントを減らします

関数名の名前に上記のキーワードのいずれかが含まれていない限り、オブジェクトを返すすべての関数が保持カウントが 0 のオブジェクトを返すことを確認することが目的 c の慣行として期待されます。(もちろん、オブジェクトを返す前に、オブジェクトに対して「release」ではなく「autorelease」を呼び出す必要があります)

これらのキーワードの 1 つを使用する場合、受信者は rf カウントが 1 であることを期待する必要があります。

これは、組み込み関数に期待することでもあります。そのため、上記の行からオブジェクト 'array' を解放しないでください。

于 2013-09-03T07:46:03.490 に答える