Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 内存泄漏-从包含自定义对象的类方法返回NSMutableArray_Iphone_Ipad_Memory Management_Memory Leaks - Fatal编程技术网

Iphone 内存泄漏-从包含自定义对象的类方法返回NSMutableArray

Iphone 内存泄漏-从包含自定义对象的类方法返回NSMutableArray,iphone,ipad,memory-management,memory-leaks,Iphone,Ipad,Memory Management,Memory Leaks,我正在使用DBManager类从SQlite数据库重新运行数据。该类包含通过从数据库获取来返回MutableArray的方法。像贝娄一样 + (NSMutableArray *) getSaleForYear : (NSString *) year { if ([DBManager openDBConnection]) { NSMutableArray * sales = [[NSMutableArray alloc] initWithCapacity:1];

我正在使用DBManager类从SQlite数据库重新运行数据。该类包含通过从数据库获取来返回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]);
}
这种方法为函数的迭代调用创建内存泄漏。
请说明泄漏原因和解决方法。

您可能应该颠倒这些代码行:

arr = nil;
[arr release];
这样:

[arr release];
arr = nil;
  • 您在释放前设置了
    arr=nil
    ,该
    [arr release]
    无效
  • 不能循环遍历数组并释放每个对象(请参见下面的fluchtpunkt注释)
  • 无需检查向nil发送消息是否有效
  • 我会写:

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

    第二点应该是“你不能循环…”。当外部数组被释放时,每个对象都将从数组中移除,并将获得另一个释放调用。但它已经手动发布了。->内存例外,我添加的那个循环只是为了测试它是否能解决我的问题。因为我无法看到仅为
    [arr release]