【问题标题】:Memory Leaks - Returning NSMutableArray from class method containing Custom Objects内存泄漏 - 从包含自定义对象的类方法返回 NSMutableArray
【发布时间】:2011-03-09 09:24:16
【问题描述】:

我正在使用 DBManager 类从 SQlite 数据库中重新运行数据。该类包含通过从数据库中获取 MutableArray 来返回 MutableArray 的方法。像下面这样..

+ (NSMutableArray *) getSaleForYear : (NSString *) year {

    if ([DBManager openDBConnection]) {

        NSMutableArray * sales = [[NSMutableArray alloc] initWithCapacity:1];

        const char *q = "SELECT sales, quarter FROM sale where year like ? order by quarter";
        sqlite3_stmt *selectstmt;
        if (sqlite3_prepare_v2(database, q, -1, &selectstmt, NULL) == SQLITE_OK) {

            if(sqlite3_bind_text(selectstmt, 1, [year UTF8String] , -1, SQLITE_TRANSIENT) != SQLITE_OK){
                NSLog(@"bind error : %@", [NSString stringWithUTF8String: sqlite3_errmsg(database)]);
                return nil;
            }

            while(sqlite3_step(selectstmt) == SQLITE_ROW) {
                float sale = sqlite3_column_double(selectstmt, 0);
                    //NSString * quarter = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];
                NSString * quarter = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];

                ChartData * b1 = [[ChartData alloc] initwithdata:quarter y:sale];
                [sales addObject:b1];
                [b1 release];
                [quarter release];
            }
        }

        sqlite3_finalize(selectstmt);
        [DBManager closeDBConnection];
        return [sales autorelease];
    }else {
        return nil;
    }
}

我正在调用类似的方法。

- (IBAction) getData {

    NSLog(@"getdata");

    if (arr != nil) {
        for (ChartData * cd in arr) {
            [cd release];
        }
        arr = nil;
        [arr release];
    }

    arr = [[DBManager getSaleForYear:@"2010-11"] copy];
    NSLog(@"count %d ", [arr count]);
}

这种方法会为函数的迭代调用造成内存泄漏。 请提出泄漏原因和解决方案。

【问题讨论】:

    标签: iphone ipad memory-management memory-leaks


    【解决方案1】:
    1. 你在发布之前设置了arr = nil,这个[arr release]没有效果
    2. 您不能循环遍历数组并释放每个对象(请参阅下面的 fluchtpunkt 评论)。
    3. 无需检查arr == nil向nil发送消息是否有效。

    我会写:

    - (IBAction)getData {
        NSLog(@"getdata");
    
        [arr release];
    
        arr = [[DBManager getSaleForYear:@"2010-11"] copy];
        NSLog(@"count %d ", [arr count]);
    }
    

    【讨论】:

    • 第二点应该是“你不能循环......”。当外部数组被释放时,每个对象都将从数组中删除,并会得到另一个释放调用。但它已经手动发布了。 -> 内存异常
    • 谢谢,我添加的那个循环只是为了测试它是否能解决我的问题。因为我看不到只为 [arr release] 调用 Chartdata 的 dealloc
    【解决方案2】:

    您可能应该反转这些代码行:

    arr = nil;
    [arr release];
    

    这样:

    [arr release];
    arr = nil;
    

    【讨论】:

      猜你喜欢
      • 2011-02-24
      • 2011-07-05
      • 1970-01-01
      • 2011-01-26
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 2011-01-21
      相关资源
      最近更新 更多