1

カスタム UIPickerView を構築して、ユーザーが設定アプリに移動して電話全体で 24 時間制をオンにすることなく、24 時間として時間を選択できるようにします。いくつかの文字列と配列の頑固なリークがあり、本当に助けが必要でした。

文字列で作成している配列が使用される場所は 3 つだけです。時間と分は両方ともNSArray合成されたプロパティであり、ivar です。

a) 文字列と配列が実際に作成される viewWillAppear:animated 内:

if (TwentyFourHourMode) {
    //set up arrays for 24 hour picker

    NSMutableArray *hoursMutable = [[NSMutableArray alloc] init];
    NSString *hourString;
    for (int i = 0; i < 24; i++) {
        if (i < 10) {
            hourString = [NSString stringWithFormat:@"0%i", i];
        } else {
            hourString = [NSString stringWithFormat:@"%i", i];
        }
        [hoursMutable addObject:hourString];
    }
    self.hours = [[NSArray alloc] initWithArray:hoursMutable];
    [hoursMutable release];

    NSMutableArray *minutesMutable = [[NSMutableArray alloc] init];
    NSString *minuteString;
    for (int i = 0; i < 60; i++) {
        if (i < 10) {
            minuteString = [NSString stringWithFormat:@"0%i", i];
        } else {
            minuteString= [NSString stringWithFormat:@"%i", i];
        }
        [minutesMutable addObject:minuteString];
    }
    self.minutes = [[NSArray alloc] initWithArray:minutesMutable];
    [minutesMutable release];
    //more stuff which does not leak or reference the arrays/strings in question
} else {
    //unrelated crap
}

b) 私の UIPickerView デリゲート メソッド - これら 2 つの配列を使用するすべてのもの:

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 2;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    if (component == 0) {
        return self.hours.count;
    } else if (component == 1) {
        return self.minutes.count;
    } else {
        return 0;
    }    
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    if (component == 0) {
        return [self.hours objectAtIndex:row];
    } else if (component == 1) {
        return [self.minutes objectAtIndex:row];
    } else {
        return nil;
    }
}

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
    switch(component) {
        case 0: return 44;
        case 1: return 50;
        default: return 44;
    }

}

- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    if (component == 0) {
        [hour24 release];
        hour24 = [self.hours objectAtIndex:row];
        [hour24 retain];
    } else if (component == 1) {
        [minute24 release];
        minute24 = [self.minutes objectAtIndex:row];
        [minute24 retain];
    }

c) そして最後になりましたが、dealloc で:

//set arrays to nil
self.hours = nil;
self.minutes = nil;

//release arrays
[hours release];
[minutes release];

Analyze はクリーンに近づいていますが、Instruments は hourString、minuteString、および self.hours がすべてリークしていると言っています。本当に私を夢中にさせるのは、self.minutesがリークされておらず、self.hoursと同じ形式のコードであるように見えることです-コピーして貼り付けても、同じリーク/リークなしの組み合わせが得られます.

これがどこから来ているかを理解できたら、私はのろわれます。何か案は?あなたが助ける必要があるかもしれないさらなるコードはありますか?みんなありがとう!

編集:EmptyStackの提案は停止self.hoursminuteString、リークされていませんhourStringが、まだリークしており、上記のもののすぐ下のこのコードに新しいリークがありますviewWillAppear:animatedself.incomingTimeは合成されたNSStringプロパティであり、ここのすべての配列はローカルで初期化されています):

NSArray *splitStrings = [self.incomingTime componentsSeparatedByString:@":"];
NSString *hourToDisplay = [splitStrings objectAtIndex:0];
//set this here so it doesn't give a null value
hour24 = [[NSString alloc] initWithString:hourToDisplay];
NSString *minuteSplitter = [splitStrings objectAtIndex:1];
NSArray *splitMinutes = [minuteSplitter componentsSeparatedByString:@" "]; 
NSString *minuteToDisplay = [splitMinutes objectAtIndex:0];
minute24 = [[NSString alloc] initWithString:minuteToDisplay];

編集 2:ああ、大声で叫ぶために、今minuteStringまた漏れています。頭が爆発する前に寝ます。一晩中の提案は大歓迎です。

4

2 に答える 2

2

問題は次の行にあります。

self.hours = [[NSArray alloc] initWithArray:hoursMutable];
self.minutes = [[NSArray alloc] initWithArray:minutesMutable];

時間「保持されたプロパティ」であり、オブジェクトをプロパティに割り当てながら割り当てているようです。たとえば、最初の行では、 retainCount[NSArray alloc]を増加させ、セッターは保持カウントを増加させます。最後に、retainCountが になり、これらのオブジェクトを解放した後でもリークが発生します。このような場合は、便利なコンストラクターを使用できます。1self.hours12

self.hours = [NSArray arrayWithArray:hoursMutable];
self.minutes = [NSArray arrayWithArray:minutesMutable];

さらに簡単な方法は、これらの配列を次のように直接割り当てることです。

self.hours = hoursMutable;
self.minutes = minutesMutable;
于 2011-10-04T09:21:24.157 に答える
1

さて、将来これに出くわした人のために、最終的にそれを見つけました.deallocで適切にリリースされhour24minute24いなかったため、文字列と配列がいたるところにリークしていました. 2回目の編集で投稿されたコードをコメントアウトし、リークが発生するまで1行ずつ元に戻すことで見つけました。提案をありがとう!

于 2011-10-05T18:37:38.667 に答える