循环内的Objective-C循环和@autoreleasepool的ARC内存问题

时间:2015-01-20 09:45:46

标签: objective-c out-of-memory automatic-ref-counting

我有一种情况,我必须在另一个for循环中使用for循环。

当迭代次数不是很大(<10000)时,它可以正常工作,并且在该过程完成后,内存被正确清除并且应用程序正常工作。

但有时迭代次数可能非常大。内部循环总是有一些有限的数量(在我的情况下为20),但外部循环从非常小到非常大(可以达到100000)。

与此类似的内容将导致内存不足错误,应用程序将被终止:

    @autoreleasepool {
    NSMutableArray *array = [NSMutableArray array];
    for(int i=0; i<1000000;i++){
        @autoreleasepool {
            NSString *dataString = dataArray[i];
            NSArray *temp = [dataString componentsSeparatedByString:@","];

            NSString *string1 = @"";
            NSString *string2 = @"";
            NSString *string3 = @"";

            for(int j=0; j<20; j++){
                NSString *tag = temp[j];
                NSArray *kv = [tag componentsSeparatedByString:@":"];
                switch ([kv[0] intValue]) {
                    case 0:
                        string1 = kv[1];
                        break;
                    case 1:
                        string2 = kv[1];
                        break;
                    case 2:
                        string3 = kv[1];
                        break;

                    default:
                        break;
                }
            }

            NSString *final = [NSString stringWithFormat:@"%@ %@ %@", string1, string2, string3];
            [array addObject:final];

        }
    }
    [self process:array];
    // process array
}

@autoreleasepool似乎根本没有工作(几乎相同数量的内存可以在有和没有@autoreleasepool块的情况下使用)

我尝试删除内部循环(仅用于测试),代码正常工作,每次迭代后释放内存。但是当使用内部循环时,内存不会被释放,最终应用程序因内存不足而终止。

任何人都可以告诉我,如果我在这里做错了什么,我找不到解决办法。

EDITED

噢,我很愚蠢:)

我发现了这个问题,它与循环或任何事情无关。 其中一个开关案例有一个日期字符串,我需要该字符串转换为另一种日期格式

    NSDateFormatter *dFormatter = [[NSDateFormatter alloc] init];
    [dFormatter setDateFormat:fromFormat];
    NSDate *date = [dFormatter dateFromString:dateString];
    [dFormatter setDateFormat:toFormat];
    NSString *newDateString = [dFormatter stringFromDate:date];
    return newDateString;

因此每个外部循环此代码将运行一次,这是使我的记忆保持填充直到崩溃的代码。

所以我每次都停止创建新的NSDateFormatter,并将两个格式化程序作为全局格式化程序。所以现在我的代码运行顺利:)

    [self.formatter setDateFormat:fFormat];
    NSDate *date = [self.formatter dateFromString:dateString];
    [self.dOnlyFormatter setDateFormat:tFormat];
    NSString *newDateString = [self.dOnlyFormatter stringFromDate:date];
    return newDateString;

但是我不明白为什么这些NSDateFormatter对象在方法完成后没有得到dealloc。

1 个答案:

答案 0 :(得分:-1)

试试这个:

NSMutableArray *array = [NSMutableArray array];
NSString *final;
NSString *string1;
NSString *string2;
NSString *string3;
NSString *const empty = @"";
NSString *const x = @"x";
NSString *const y = @"y";
NSString *const z = @"z";

for(int i=0; i<100000;i++){

        string1 = empty;
        string2 = empty;
        string3 = empty;

        for(int j=0; j<20; j++){ // if we remove this loop this works perfectly
            switch (j) {
                case 0:
                    string1 = x;
                    break;
                case 1:
                    string2 = y;
                    break;
                case 2:
                    string3 = z;
                    break;

                default:
                    break;
            }
        }

        final = [NSString stringWithFormat:@"%@ %@ %@", string1, string2, string3];

}

作为积极的副作用,它可能更快。