【问题标题】:Memory leaks in NSMutableDictionaryNSMutableDictionary 中的内存泄漏
【发布时间】: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&lt;=x;i++){ ?!
  • 你是对的:for (int i=0; i

标签: iphone objective-c


【解决方案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] 行?也许你得到一个空指针。在这种情况下修改上面的代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多