Я не могу понять, почему моему приложению iPhone не хватает памяти - PullRequest
2 голосов
/ 12 января 2011

Я загружаю кучу данных из текстового файла в CoreData. По какой-то причине каждая итерация цикла for (строка в строках) в приведенном ниже коде выделяет новую память. Работает нормально до тех пор, пока не сможет выделить новую память. Я не понимаю, почему он не использует одну и ту же память для каждой итерации. Что я делаю неправильно? Любая помощь будет оценена.

`

- (IBAction) loadDataInThread {

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"MileMarkers" ofType:@"csv"];
NSData *myString = [NSString stringWithContentsOfFile:filePath];
NSArray *lines = [myString componentsSeparatedByString:@"\r"];
status.hidden = FALSE;
// NSManagedObjectContext *context = [self managedObjectContext]; 
NSFileManager *fileman = [NSFileManager defaultManager];
NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Tiles"];
NSString *line;
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setLocale:[NSLocale currentLocale]]; 
[myNumFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle];

NSManagedObject *newManagedObject;
NSArray *fields;
// NSLog(@"Loading Markers");
for (line in lines) {
    fields = [line componentsSeparatedByString:@","];
    self.stat = [NSString stringWithFormat:@"%@ %@ %@ %@",[fields objectAtIndex:0],[fields objectAtIndex:1],[fields objectAtIndex:2],[fields objectAtIndex:3]];

    NSLog(stat);
    [self performSelectorOnMainThread:@selector(updateStatus) withObject:nil waitUntilDone:YES];

    newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"MileMarkers" inManagedObjectContext:self.managedObjectContext];

    NSNumber *f1 = [myNumFormatter numberFromString:[fields objectAtIndex:0]];
    NSNumber *f2 = [myNumFormatter numberFromString:[fields objectAtIndex:1]];
    NSNumber *f3 = [myNumFormatter numberFromString:[fields objectAtIndex:2]];
    NSNumber *f4 = [myNumFormatter numberFromString:[fields objectAtIndex:3]];

    [newManagedObject setValue:f1  forKey:@"ICWID"];
    [newManagedObject setValue:f2  forKey:@"MileMarker"];
    [newManagedObject setValue:f3 forKey:@"Latitude"];
    [newManagedObject setValue:f4 forKey:@"Longitude"];

    NSMutableArray *charts = [[NSMutableArray alloc] initWithCapacity:4];

    NSDirectoryEnumerator *e = [fileman enumeratorAtPath:tileDirectory];
    NSString *path;
    int idx = 0;
    /*
    for (path in e) {
        NSString *pathFileName = [NSString stringWithFormat:@"%@/%@/tilemapresource.xml",tileDirectory,[path stringByDeletingPathExtension]];
//      NSLog(@"parsing %@",pathFileName);

            BOOL checkFile = [self checkForLatLong:pathFileName latitude:f3 longitude:f4 ]; 
            if (checkFile) {
                NSLog(@"Match %d",idx);
                if (idx < 4){
                    self.counter.text = [NSString stringWithFormat:@"%d",idx];
                    [charts insertObject:path atIndex:idx];
                    idx++;
                }
            }       

        }
    [path release];

    for (int lp=1; lp<[charts count]; lp++) {
        NSString *keyName = [NSString stringWithFormat:@"Chart%d",lp+1];
        [newManagedObject setValue:[charts objectAtIndex:lp] forKey:keyName];
        }
    [charts release];
    */

    NSError *error = nil;
    if (![self.managedObjectContext save:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    [error release];
}
[myNumFormatter release];

NSLog(@"Markers Loaded");
[self performSelectorOnMainThread:@selector(dataLoaded) withObject:nil waitUntilDone:YES];
[pool release];

} `

Ответы [ 5 ]

7 голосов
/ 12 января 2011

Вероятно, вы создаете много автоматически выпущенных объектов в этом цикле. Помните, что автоматически выпущенные объекты остаются в силе до конца всего цикла событий, после чего пул автоматического выпуска очищается. Обычно этот процесс работает более или менее незаметно, но если у вас есть циклы, которые выделяют много автоматически выпущенных объектов, вы можете исчерпать кучу.

Вы можете смягчить это, создав и опустошив внутренний пул авто-релиза в вашем цикле, например:

for (line in lines) {  
    NSAutoreleasePool * localPool = [[NSAutoreleasePool alloc] init];
    ...
    [localPool release];
}

Вы также должны явно освобождать любые созданные / сохраненные объекты, которые вам больше не нужны, например, "диаграммы" и т. Д. В приведенном выше.

3 голосов
/ 12 января 2011

Изменяемый массив "charts" не выпускается.

Эта строка,

NSMutableArray *charts = [[NSMutableArray alloc] initWithCapacity:4];
1 голос
/ 12 января 2011

Вы должны выпустить диаграммы после того, как вы закончите с этим, например:

[a1 release]
0 голосов
/ 12 января 2011

В Objective-C всегда запоминайте эту строку тега When you use alloc or new or make a copy, you should definitely release it.

То есть вы управляете ресурсами, а не компилятором. Так что ваша задача - освободить их.

Дополнительная информация

0 голосов
/ 12 января 2011

Классическая проблема управления памятью.

Проверьте это ... управление памятью

Также существует множество других ссылок ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...