Мой вопрос об основных данных и использовании памяти. Я использовал основные данные раньше, но на этот раз объем данных был выше, и это заставило меня понять, что нужно знать намного больше. Я видел, что есть несколько других подобных постов, и я получил от них интересную информацию, но после ее применения мои приложения по-прежнему зависают. Я занимаюсь этим вопросом уже неделю. Кто-нибудь, пожалуйста, помогите.
По сути, у меня есть три последовательных одинаковых цикла по 64, 15 и 17 итераций соответственно. Они отлично работают на симуляторе. Протестировано на нескольких iPad, они получают предупреждения памяти и они терпят крах на той же итерации (номер 34 первого цикла). Протестировано на iPad 2, оно рухнет под номером 14 второго цикла. Инструменты показывают использование памяти около 1,5 МБ как в реальном времени, так и в целом. Есть утечки на несколько килобайт.
Циклы выполняют следующее (код ниже)
- Выполнить выборку с основными данными
- Для каждой записи взять параметр, хранящийся в качестве атрибута свойства строки (String)
- Вызов процедуры, которая принимает этот параметр и возвращает данные (около сотни КБ).
- Сохранить эти данные в другом атрибуте свойства (Transformable) той же строки
Довольно распространенная задача, не правда ли?
Теперь, так как у меня возникли проблемы с памятью, я попытался использовать все известные мне инструменты, а именно:
- освободить принадлежащие объекты как можно скорее
- создавать пулы авто-релиза и сливать их как можно скорее для не принадлежащих объектов
- сохранить контекст как можно скорее
- превратить объекты в недостатки как можно скорее
После применения всех этих приемов я получил потрясающий результат: приложение вылетает в тот же момент, что и раньше.
Вот это код.
- (void) myMainProcedure {
[self performLoop1];
[self performLoop2]; // Similar to loop1
[self performLoop3]; // Similar to loop1
}
- (void) performLoop1 {
NSError * error = nil;
NSAutoreleasePool * myOuterPool;
NSAutoreleasePool * myInnerPool;
NSManagedObjectContext * applicationContext = [[[UIApplication sharedApplication] delegate] managedObjectContext];
[applicationContext setUndoManager:nil];
NSEntityDescription * myEntityDescription = [NSEntityDescription entityForName:@"EntityName"
inManagedObjectContext:applicationContext];
NSFetchRequest * myFetchRequest = [[NSFetchRequest alloc] init];
[myFetchRequest setEntity:myEntityDescription];
NSString * column = @"columnName";
NSPredicate * aWhereClause = [NSPredicate predicateWithFormat:
@"(%K = %@)", column, [NSNumber numberWithInt:0]];
[myFetchRequest setPredicate: aWhereClause];
myOuterPool = [[NSAutoreleasePool alloc] init];
NSArray * myRowsArray = [applicationContext executeFetchRequest:myFetchRequest
error:&error];
NSMutableArray * myRowsMutableArray = [[NSMutableArray alloc] initWithCapacity:0];
[myRowsMutableArray addObjectsFromArray: myRowsArray];
[myOuterPool drain];
[myFetchRequest release];
EntityName * myEntityRow;
int totalNumberOfRows = [myRowsMutableArray count];
myOuterPool = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < totalNumberOfRows; i++) {
myInnerPool = [[NSAutoreleasePool alloc] init];
myEntityRow = [myRowsMutableArray objectAtIndex:0];
NSString * storedSmallAttribute = myEntityRow.smallAttribute;
UIImageView * largeData = [self myMethodUsingParameter: smallAttribute];
myEntityRow.largeAttribute = largeData;
[myRowsMutableArray removeObjectAtIndex:0];
[applicationContext save:&error];
[applicationContext refreshObject:myEntityRow mergeChanges:NO];
[myInnerPool drain];
[largeData release];
}
[myOuterPool drain];
[myRowsMutableArray release];
}
- (UIImageView *) myMethodUsingParameter : (NSString *) link {
UIImageView * toBeReturned = nil;
NSURL *pdfURL = [NSURL fileURLWithPath:link];
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,pageRect);
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0, pageRect.size.height);
CGContextScaleCTM(context, 1, - 1);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
UIImage *imageToBeReturned = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CFRelease(pdf);
toBeReturned = [[UIImageView alloc] initWithImage:imageToBeReturned];
UIGraphicsEndImageContext();
return toBeReturned;
}
Обратите внимание, что
- Изменяемый массив был представлен как (явно бесполезная) стратегия для
есть объекты, выпущенные раньше
- Добавлены бассейны и часть той же стратегии
- Заявление о качестве интерполяции было единственным, которое улучшило
ситуация (скажем, чтобы перенести аварию
немного вперед)
- Сохранять счет для управляемых объектов в пределах циклов от 6 до 10
(?) Я знаю, что RC не является ценным
информация, но все же, я сделал тест
и я узнал, что могу отправить
несколько выпусков сообщений для управляемых
объекты, прежде чем заставить приложение
крушение за это. Но дело в том, что
Я не должен выпускать
объект, которым я не владею? ....
- Сущность, на которую устанавливается запрос, также получила
двунаправленные отношения с
другие лица, но все же, это
отношение?
Спасибо.