1

我在遍历 SQLite 数据库中执行批量插入的循环时遇到了一个严格的基于内存的问题。

我很确定这是关于内存的,我无法指出导致问题的变量。我已尽我所能释放所有分配的内容。

到目前为止,通过仪器分析没有内存泄漏。代码片段如下:

int m=0;

while ([arrData count]!=0) {

if (newQuery) {

    exeQuery = query;
    newQuery = false;

}
else 
{
    exeQuery=[exeQuery stringByAppendingFormat:@" UNION"];
}

NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithDictionary:[arrData objectAtIndex:0]];

[data removeObjectForKey:@"statement"];
[data removeObjectForKey:@"datetime_stamp"];

NSString *strVal=@"";
NSString *_value=@"";

int i=0;
    for(;i<[keys  count]-1;i++)
    {
        if(_value==nil || _value==NULL){
            _value=@"";
        }

        _value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
        _value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

        strVal=[strVal stringByAppendingFormat:@"'%@',",_value];

    }

if(_value==nil || _value==NULL){
    _value=@"";
}

_value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
_value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

strVal=[strVal stringByAppendingFormat:@"'%@'",_value];


exeQuery=[exeQuery stringByAppendingFormat:@" SELECT %@",strVal];


if (m!=0 && m%499==0) {

    [DataSource executeQuery:exeQuery];

    //db.execute(exeQuery);
    newQuery = true;
}

[data release];

[arrData removeObjectAtIndex:0];

m++;
}

for (;m<locations_length; m++) {

if (newQuery) {

    exeQuery = query;
    newQuery = false;

}
else 
{
    exeQuery=[exeQuery stringByAppendingFormat:@" UNION"];
}

NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithDictionary:[arrData objectAtIndex:m]];

[data removeObjectForKey:@"statement"];
[data removeObjectForKey:@"datetime_stamp"];

NSString *strVal=@"";
NSString *_value=@"";

int i=0;
    for(;i<[keys  count]-1;i++)
    {
        if(_value==nil || _value==NULL){
            _value=@"";
        }

        _value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
        _value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

        strVal=[strVal stringByAppendingFormat:@"'%@',",_value];

    }

if(_value==nil || _value==NULL){
    _value=@"";
}

_value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
_value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

strVal=[strVal stringByAppendingFormat:@"'%@'",_value];


exeQuery=[exeQuery stringByAppendingFormat:@" SELECT %@",strVal];


if (m!=0 && m%499==0) {

    [DataSource executeQuery:exeQuery];

    //db.execute(exeQuery);
    newQuery = true;
}

[data release];
}

任何帮助是极大的赞赏。请携手..!

提前致谢。

4

3 回答 3

1

在不知道您在 [keys count] 中经历了多少次迭代的情况下,您正在执行大量 NSString 操作。每个“stringBy...”消息都会分配一个新的自动释放的 NSString 实例,直到你退出循环才会被释放。您可能需要考虑改用 NSMutableString 并使用

replaceOccurrencesOfString:withString:options:range:

减少您正在创建的自动释放对象的数量(从而减少应用程序的内存占用)。请参阅NSMutableString 文档。否则,我建议使用 Xcode 中的分配工具或类似工具来尝试仔细检查您的内存占用

于 2012-08-21T12:27:28.097 回答
1

很明显,我们正在使用一个每个实例都会发生突变的字符串,因此 nsmutablestring 是优化的解决方案。在分析函数时:

[NSMutableString replaceOccurrencesOfString:@"'" withString:@"''"]
[NSMutableString  appendString:]

在仪器中,与您使用过的仪器进行比较时,它们会留下更少的内存足迹。

于 2012-08-25T09:18:14.683 回答
0

对于使用 Sqlite 或 Core Data 在数据库中批量插入记录,总是更喜欢在 @autoreleasepool{} 中使用循环,因为这样,所有处于自动释放模式的对象,在立即使用后将变为 nil。

int m=0;

while ([arrData count]!=0) {

@autoreleasepool{

if (newQuery) {

    exeQuery = query;
    newQuery = false;

}
else 
{
    exeQuery=[exeQuery stringByAppendingFormat:@" UNION"];
}

NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithDictionary:[arrData objectAtIndex:0]];

[data removeObjectForKey:@"statement"];
[data removeObjectForKey:@"datetime_stamp"];

NSString *strVal=@"";
NSString *_value=@"";

int i=0;
    for(;i<[keys  count]-1;i++)
    {
        if(_value==nil || _value==NULL){
            _value=@"";
        }

        _value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
        _value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

        strVal=[strVal stringByAppendingFormat:@"'%@',",_value];

    }

if(_value==nil || _value==NULL){
    _value=@"";
}

_value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
_value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

strVal=[strVal stringByAppendingFormat:@"'%@'",_value];


exeQuery=[exeQuery stringByAppendingFormat:@" SELECT %@",strVal];


if (m!=0 && m%499==0) {

    [DataSource executeQuery:exeQuery];

    //db.execute(exeQuery);
    newQuery = true;
}

[data release];

[arrData removeObjectAtIndex:0];

m++;
}

for (;m<locations_length; m++) {

if (newQuery) {

    exeQuery = query;
    newQuery = false;

}
else 
{
    exeQuery=[exeQuery stringByAppendingFormat:@" UNION"];
}

NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithDictionary:[arrData objectAtIndex:m]];

[data removeObjectForKey:@"statement"];
[data removeObjectForKey:@"datetime_stamp"];

NSString *strVal=@"";
NSString *_value=@"";

int i=0;
    for(;i<[keys  count]-1;i++)
    {
        if(_value==nil || _value==NULL){
            _value=@"";
        }

        _value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
        _value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

        strVal=[strVal stringByAppendingFormat:@"'%@',",_value];

    }

if(_value==nil || _value==NULL){
    _value=@"";
}

_value=[NSString stringWithFormat:@"%@",[data objectForKey:[keys objectAtIndex:i]]];
_value=[_value stringByReplacingOccurrencesOfString:@"'" withString:@"''"];

strVal=[strVal stringByAppendingFormat:@"'%@'",_value];


exeQuery=[exeQuery stringByAppendingFormat:@" SELECT %@",strVal];


if (m!=0 && m%499==0) {

    [DataSource executeQuery:exeQuery];

    //db.execute(exeQuery);
    newQuery = true;
}

[data release]; 

}


}
于 2012-08-21T11:44:13.443 回答