UIPickerView 方法中的奇怪泄漏
构建一个自定义 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 是干净的,但是 Instruments告诉我 hourString、minionString 和 self.hours 都被泄露了。真正让我抓狂的是 self.mins 没有被泄露,而且它的代码格式似乎与 self.hours 相同 - 我什至复制粘贴,仍然得到相同的泄漏/无泄漏组合。
如果我能弄清楚这是从哪里来的,我就该死了。有什么想法吗?你们可能还需要帮助吗?谢谢你们!
编辑:EmptyStack的建议阻止了self.hours
和mintString
被泄露,但是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: 噢,大声喊叫,现在 minionString
又泄漏了。在我的头爆炸之前我要去睡觉了。任何过夜的建议都将受到欢迎。
Building a custom UIPickerView for so I can let my users select time as 24 hours without having to go into the Settings app and turn on 24 hour time for the entire phone. Got some stubborn leaks of a couple strings and an array, and I could really use some help.
There are only three places where the arrays I'm creating with the strings are used. hours and minutes are both NSArray
synthesized properties as well as ivars.
a) In viewWillAppear:animated, where the strings and arrays are actually created:
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) in my UIPickerView delegate methods - everything that uses these two arrays:
-(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) and last but not least, in dealloc:
//set arrays to nil
self.hours = nil;
self.minutes = nil;
//release arrays
[hours release];
[minutes release];
Analyze is coming up clean, but Instruments is telling me hourString, minuteString, and self.hours are all being leaked. What really drives me nuts is that self.minutes isn't being leaked and it appears to be the same format of code as self.hours - I even copy-pasted and still get the same leak/no leak combo.
I'll be damned if I can figure out where this is coming from. Any ideas? Any further code y'all might need to help? Thanks, guys!
Edit: EmptyStack's suggestion stopped self.hours
and minuteString
from being leaked, but hourString
is still leaking and there's now a new leak in this code just below the stuff above in viewWillAppear:animated
(self.incomingTime
is a synthesized NSString
property, all arrays here are initialized locally):
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];
Edit 2: Oh, for crying out loud, now minuteString
is leaking again. I'm going to bed before my head explodes. Any suggestions overnight would be most welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题在以下几行中,
似乎小时和分钟是“保留属性”并且您正在分配对象,同时将其分配给属性。例如,在第一行,
[NSArray alloc]
将 retainCount 增加1
,并且设置器self.hours
反过来,retainCount 增加1
。最后,retainCount 变为2
,即使在释放这些对象后也会导致泄漏。在这些情况下,您可以使用便捷构造函数。甚至更简单的方法是像这样直接分配这些数组,
The problems are in the following lines,
It seems hours and minutes are "retained properties" and you are allocating objects while assigning it to the properties. For example on the first line,
[NSArray alloc]
increases the retainCount by1
and the setterself.hours
in turn increases the retainCount by1
. Finally the retainCount becomes2
, which causes the leak even after you release those objects. You can use convenience constructors in these cases.And even a simpler way is to directly assign those arrays like this,
好吧,终于找到了,对于将来遇到这个问题的人来说:
hour24
和min24
没有在 dealloc 中正确释放,因此它在整个过程中泄漏了字符串和数组。地方。我通过注释掉第二次编辑中发布的代码并将其逐行放回原处,直到泄漏发生,找到了它。感谢您的建议!Okay, finally found it, for anyone stumbling across this in the future:
hour24
andminute24
were not being properly released in dealloc, so it was leaking strings and arrays all over the place. I found it by commenting out the code posted in the 2nd edit and putting it back in line by line until the leak sprang up. Thanks for the suggestions!