カスタム 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.hours
しminuteString
、リークされていませんhourString
が、まだリークしており、上記のもののすぐ下のこのコードに新しいリークがありますviewWillAppear:animated
(self.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
また漏れています。頭が爆発する前に寝ます。一晩中の提案は大歓迎です。