构建自定义UIPickerView,我可以让我的用户选择24小时的时间,而无需进入“设置”应用并为整个手机启用24小时制。得到了几个字符串和数组的顽固泄漏,我真的可以使用一些帮助。
我使用字符串创建的数组只有三个位置。小时和分钟都是NSArray
合成属性以及ivars。
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委托方法中 - 使用这两个数组的所有内容:
-(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即将推出,但是仪器告诉我,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
再次泄漏。在我的脑袋爆炸之前,我要睡觉了。隔夜的任何建议都是最受欢迎的。
答案 0 :(得分:2)
问题如下:
self.hours = [[NSArray alloc] initWithArray:hoursMutable];
self.minutes = [[NSArray alloc] initWithArray:minutesMutable];
似乎小时和分钟 “保留属性” ,并且在分配对象时分配对象属性。例如,在第一行,[NSArray alloc]
将{em> retainCount 增加1
,而setter self.hours
又将retainCount增加1
。最后, retainCount 变为2
,即使在释放这些对象后也会导致泄漏。在这些情况下,您可以使用便捷构造函数。
self.hours = [NSArray arrayWithArray:hoursMutable];
self.minutes = [NSArray arrayWithArray:minutesMutable];
甚至更简单的方法是直接分配这样的数组,
self.hours = hoursMutable;
self.minutes = minutesMutable;
答案 1 :(得分:1)
好的,终于找到了它,对于将来遇到这种情况的人来说:hour24
和minute24
没有在dealloc中正确发布,所以它在整个地方泄漏了字符串和数组。我发现它是通过评论第二次编辑中发布的代码并将其重新排列,直到泄漏出现。谢谢你的建议!