NSDateFormatter内存泄漏?
我有NSDateFormatter dateFromString:
方法的问题。 有一个包含stringdate的字典数组,我想将它们转换为NSDates
。 但是每次我调用这个方法时都会有一个巨大的堆增长(我需要多次调用它,因为它是一个“更新”方法)。 我也在背景线程中调用它,并打开ARC。 我究竟做错了什么? 任何帮助,请。
更新:函数的完整代码:
- (GraphController *) initGraphWithData: (NSArray *) points forInterval: (GraphInterval) interval andFrame: (CGRect) frame gestures: (BOOL) gestures secondGraph: (NSArray *) secondPoints graphNames: (NSArray *) graphNames { self = [super init]; _calendar = [NSCalendar currentCalendar]; _secondPoints = secondPoints; _graphNames = graphNames; [self.view setFrame:frame]; _points = [[NSMutableArray alloc] init]; double minValue = HUGE_VALF, maxValue = -HUGE_VALF; NSDate *minDate = [NSDate date], *maxDate = [NSDate dateWithTimeIntervalSince1970:0]; NSMutableDictionary *datesTable = [[NSMutableDictionary alloc] init]; int index = 0; for(NSArray *pointArray in points){ NSDictionary *point = pointArray[0]; NSMutableDictionary *newPoint = [[NSMutableDictionary alloc] initWithDictionary:point]; // convert date NSString *dateString = (NSString *)[point objectForKey:@"date"]; NSLog(@"dateString to convert: %@", dateString); [_dateFormatter setDateFormat:@"MM/dd/yyyy"]; NSDate *date = [_dateFormatter dateFromString: dateString]; [newPoint setObject: date forKey:@"date"]; // convert numbers [newPoint setObject: [NSNumber numberWithFloat:[((NSString *)[point objectForKey:@"value"]) floatValue]] forKey:@"value"]; if(secondPoints) [newPoint setObject: [NSNumber numberWithFloat:[((NSString *)[secondPoints[index] objectForKey:@"value"]) floatValue]] forKey:@"secondValue"]; [newPoint setObject: [NSNumber numberWithInt:index] forKey:@"index"]; // min and max if([[newPoint objectForKey:@"value"] floatValue] < minValue) minValue = [[newPoint objectForKey:@"value"] floatValue]; if([[newPoint objectForKey:@"value"] floatValue] > maxValue) maxValue = [[newPoint objectForKey:@"value"] floatValue]; // check second value if(self.secondPoints){ if([[newPoint objectForKey:@"secondValue"] floatValue] < minValue) minValue = [[newPoint objectForKey:@"secondValue"] floatValue]; if([[newPoint objectForKey:@"secondValue"] floatValue] > maxValue) maxValue = [[newPoint objectForKey:@"secondValue"] floatValue]; } if([[newPoint objectForKey:@"date"] timeIntervalSince1970] > [maxDate timeIntervalSince1970]) maxDate = [newPoint objectForKey:@"date"]; if([[newPoint objectForKey:@"date"] timeIntervalSince1970] < [minDate timeIntervalSince1970]) minDate = [newPoint objectForKey:@"date"]; [self.points addObject:newPoint]; [datesTable setObject:newPoint forKey: [[NSNumber numberWithDouble:[date timeIntervalSince1970]] stringValue] ]; index++; } // set draw parameters _drawVars = [[NSMutableDictionary alloc] init]; NSDate *startSearchDate; switch (interval) { case GraphIntervalWeek: startSearchDate = [maxDate dateByAddingTimeInterval:-7*24*3600]; break; case GraphIntervalMonth: startSearchDate = [maxDate dateByAddingTimeInterval: -31*24*3600]; break; case GraphIntervalSixMonths: startSearchDate = [maxDate dateByAddingTimeInterval:-6*31*24*3600]; break; case GraphIntervalYear: startSearchDate = [maxDate dateByAddingTimeInterval:-365*24*3600]; break; case GraphIntervalAllTime: break; default: break; } NSMutableDictionary *searchPoint; while(searchPoint == nil && [startSearchDate timeIntervalSince1970] > [minDate timeIntervalSince1970]){ searchPoint = [datesTable objectForKey:[[NSNumber numberWithDouble:[startSearchDate timeIntervalSince1970]] stringValue]]; startSearchDate = [startSearchDate dateByAddingTimeInterval:-24*3600]; } if(searchPoint != nil && interval != GraphIntervalAllTime) [self.drawVars setObject:[searchPoint objectForKey:@"index"] forKey:@"startDrawIndex"]; else [self.drawVars setObject:[NSNumber numberWithInt:0] forKey:@"startDrawIndex"]; [self.drawVars setObject:[[NSNumber numberWithFloat:minValue] copy] forKey:@"minValue"]; [self.drawVars setObject:[[NSNumber numberWithFloat:maxValue] copy] forKey:@"maxValue"]; [self.drawVars setObject:minDate forKey:@"minDate"]; [self.drawVars setObject:maxDate forKey:@"maxDate"]; [self.drawVars setObject:datesTable forKey:@"datesTable"]; // set drawImageView _drawArea = [[UIImageView alloc] initWithFrame: frame]; [self.view addSubview:self.drawArea]; // set overlayImageView for fingerInpect _inspectOverlay = [[UIImageView alloc] initWithFrame:frame]; [self.view addSubview:self.inspectOverlay]; // set hintUIView for fingerInspect _hint = [[Hint alloc] initWithFrame:frame]; [self.hint initHint]; self.hint.hidden = YES; [self.drawArea addSubview:self.hint]; UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)]; UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressHandler:)]; if(gestures) [self.view addGestureRecognizer:panRecognizer]; [self.view addGestureRecognizer:longPressRecognizer]; return self; }
我看到你正在使用Heapshot分析。 好。 这里有一些更多的细节:
现在,希望每一个Heapshot迭代都代表在你的应用程序中做一些应该返回到基本状态的东西。 例如打开和closures文档。
如果是这样的话,你的数据每次迭代显示500K-600K的增长。 这是相当多的。
请注意,试图分析最后一次迭代通常是无用的; 许多这些对象将存在,因为该应用程序的当前状态是什么。 你真的想专注于第二或第四次迭代。
至于特定date或date格式化程序泄漏的原因,请打开引用计数事件跟踪,然后查看其中一个泄漏对象的保留/释放事件。 会有一些额外的保留。
你正在做的事情是在进入循环之前init
NSDateFormatter
。 如果你期待相同的date格式( MM/dd/yyyy
),你可以把它放在同一个地方。 这可能是因为你分配了太多的对象,所以我可以build议把所有内容放在@autoreleasepool {}
(又名:autorelease内部的循环内容)。
我看到你正在分配*newPoint
内部,然后你设置该对象的date。 你以后做什么?