1

构建一个自定义 UIPickerView 以便我可以让我的用户选择 24 小时时间,而无需进入设置应用程序并为整个手机打开 24 小时时间。有一些字符串和数组的顽固泄漏,我真的可以使用一些帮助。

只有三个地方使用了我用字符串创建的数组。小时和分钟都是NSArray综合属性以及 ivars。

a) 在 vi​​ewWillAppear: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 委托方法中 - 使用这两个数组的所有内容:

-(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];

分析是干净的,但仪器告诉我 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];

似乎小时分钟“保留的属性”,您在分配对象的同时将其分配给属性。例如在第一行,[NSArray alloc]retainCount增加一个,1而setterself.hours又将retainCount 增加一个1。最后,retainCount变为2,即使在您释放这些对象后也会导致泄漏。在这些情况下,您可以使用便利构造函数。

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

甚至更简单的方法是像这样直接分配这些数组,

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

好的,终于找到了,对于任何在未来偶然发现的人:hour24并且minute24没有在 dealloc 中正确释放,所以它到处泄漏字符串和数组。我通过注释掉第二次编辑中发布的代码并将其逐行放回直到泄漏出现来找到它。感谢您的建议!

于 2011-10-05T18:37:38.667 回答