NSMutableDictionary 中的内存泄漏
Posted
技术标签:
【中文标题】NSMutableDictionary 中的内存泄漏【英文标题】:Memory leaks in NSMutableDictionary 【发布时间】:2010-08-08 11:53:53 【问题描述】:我的编码包含内存泄漏,但不知何故我找不到泄漏。
泄漏为我指明了创建“ReportDetailItems”的方式
例如areaContainer = [[[ReportDetailItem alloc] init] autorelease];
我已经看了好几个小时了,我完全不知所措,报告泄漏的对象是“ReportDetailItem”,以及这些对象中包含的 NSMutableDictionary。
请指教。
------[ReportDetailItem.h
@interface ReportDetailItem : NSObject
NSNumber *total;
NSMutableDictionary *items;
@property (nonatomic, retain) NSNumber *total;
@property (nonatomic, retain) NSMutableDictionary *items;
- (NSString *)description;
@end
------[ReportDetailItem.m
@synthesize items, total;
- (id)init
if (self = [super init])
self.items = [NSMutableDictionary dictionaryWithCapacity:0];
DLog("Alloc: %d", [items retainCount]);
return self;
- (NSString *)description
return @"ReportDetailItem";
- (void)release
[super release];
- (void)dealloc
[self.items release];
[self.total release];
items = nil;
total = nil;
[super dealloc];
@end
------[泄露代码
NSError *error;
NSArray *data = [self.managedObjectContext executeFetchRequest:request error:&error];
if (data == nil || [data count] == 0)
DLog(@"No data.")
else
for (int i=0; i < [data count]; i++)
TaskEntity *task = [data objectAtIndex:i];
NSString *areaKey = task.activity.project.area.title.text;
NSString *projectKey = task.activity.project.title.text;
NSString *activityKey = task.activity.title.text;
ReportDetailItem *areaContainer;
if (![dataSource objectForKey:areaKey])
areaContainer = [[[ReportDetailItem alloc] init] autorelease];
else
areaContainer = [dataSource objectForKey:areaKey];
areaContainer.total = [NSNumber numberWithInt:([task.seconds intValue] + [areaContainer.total intValue])];
[dataSource setObject:areaContainer forKey:areaKey];
ReportDetailItem *projectContainer;
if (![areaContainer.items objectForKey:projectKey])
projectContainer = [[[ReportDetailItem alloc] init] autorelease];
else
projectContainer = [areaContainer.items objectForKey:projectKey];
projectContainer.total = [NSNumber numberWithInt:([task.seconds intValue] + [projectContainer.total intValue])];
[areaContainer.items setObject:projectContainer forKey:projectKey];
ReportDetailItem *activityContainer;
if (![projectContainer.items objectForKey:activityKey])
activityContainer = [[[ReportDetailItem alloc] init] autorelease];
else
activityContainer = [projectContainer.items objectForKey:activityKey];
activityContainer.total = [NSNumber numberWithInt:([task.seconds intValue] + [activityContainer.total intValue])];
[projectContainer.items setObject:activityContainer forKey:activityKey];
【问题讨论】:
好吧,我不会对 iphone 的东西进行编程,但你的for
看起来不对。应该是这样的:for (int i=0; i<=x;i++)
?!
你是对的:for (int i=0; i
【参考方案1】:
找到了,泄漏的位置是我分配“dataSource”的方式
---[泄漏
- (void)viewDidLoad
[super viewDidLoad];
self.dataSource = [[NSMutableDictionary alloc] init];
[self fetchData];
---[无泄漏
- (void)viewDidLoad
[super viewDidLoad];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
self.dataSource = dict;
[dict release];
[self fetchData];
【讨论】:
您的第一次(泄漏)方法是正确的。只需要在最后抛出一个自动释放。 1 行 > 3 行。【参考方案2】:我非常怀疑您将指针分配给 ReportDetailItem 的两种方式。你为什么要首先自动释放对象?如果不试试这个
ReportDetailItem *projectContainer;
if (![areaContainer.items objectForKey:projectKey])
projectContainer = [[ReportDetailItem alloc] init];
else
projectContainer = [[areaContainer.items objectForKey:projectKey] retain];
projectContainer.total = [NSNumber numberWithInt:([task.seconds intValue] + [projectContainer.total intValue])];
[areaContainer.items setObject:projectContainer forKey:projectKey];
if(projectContainer)
[projectContainer release];
projectContainer = nil;
【讨论】:
感谢您的洞察力。我正在尝试自动释放,因为它们以某种方式泄漏了。如果我尝试你的建议,我会得到“*** -[ReportDetailItem release]: message sent to deallocated instance 0x6ed9ef0” 您是否尝试打破 [projectContainer release] 行?也许你得到一个空指针。在这种情况下修改上面的代码以上是关于NSMutableDictionary 中的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章