2016-07-19 9 views
0

Как часть приложения, которое позволяет аудиторам создавать находки и связывать с ними фотографии (сохраненные как строки Base64 из-за ограничений на веб-службу), я должен выполнить все выводы и их фотографии в рамках аудита и установить для их значения синхронизации значение true.Цель C Для циклов с @autorelease и ARC

Пока я выполняю этот цикл, я вижу всплеск памяти, скачущий со скоростью от 40 МБ до 500 МБ (примерно для 350 фотографий и 255 выводов), и это число никогда не опускается. В среднем наши пользователи создают около 1000 результатов и 500-700 фотографий, прежде чем пытаться использовать эту функцию. Я попытался использовать пулы @autorelease, чтобы сохранить память, но она, похоже, не будет выпущена.

for (Finding * __autoreleasing f in self.audit.findings){ 
     @autoreleasepool { 
      [f setToSync:@YES]; 
      NSLog(@"%@", f.idFinding); 

     for (FindingPhoto * __autoreleasing p in f.photos){ 
      @autoreleasepool { 
       [p setToSync:@YES]; 
       p = nil; 
      } 

     } 
     f = nil; 

     } 
    } 

Взаимосвязи и сохраняющие циклы выглядеть следующим образом

аудита имеет сильную ссылку Поиск

Finding имеет слабую ссылку на AUDIT и сильная ссылка на FindingPhoto

FindingPhoto имеет слабое указание на поиск

Что мне не хватает в плане возможности эффективного прохода этих объектов и устанавливают их свойства, не вызывая такого огромного всплеска в памяти. Я предполагаю, что это связано с тем, что многие строки Base64 загружаются в память при прохождении цикла, но никогда не выпускаются.

+0

Как хранятся и загружаются эти объекты? Они не будут автореализоваться, потому что они все еще сохраняются в массивах, которые вы повторяете ... – Wain

+0

Сохраняется в основных данных и загружается с использованием NSFetchRequests в MutableArray. Есть ли лучший способ загрузить их, чтобы загружать и выпускать по одному, поскольку это приводит к сбою приложения, если их слишком много. –

+0

Я должен упомянуть, что единственным выполняемым FetchRequest является объект в объекте Audit, остальные доступны через свои отношения, которые явно не загружены. –

ответ

1

Итак, во-первых, убедитесь, что у вас есть размер партии, заданный в запросе выборки. Выберите относительно небольшое число, но не слишком маленькое, потому что это не для обработки пользовательского интерфейса. Вы хотите выгрузить разумное количество объектов в память, чтобы уменьшить нагрузку на загрузку при сохранении использования памяти. Попробуйте 50 или 100 и посмотрите, как это происходит, а затем немного увеличивайте размер партии.

Если все объекты, которые вы загружаете, управляются объектами, то правильный способ их выселения во время обработки состоит в том, чтобы превратить их в неисправности. Это делается путем вызова refreshObject:mergeChanges: в контексте. НО - это отбрасывает любые изменения, и ваш цикл специально предназначен для внесения изменений.

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

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

+0

Большое вам спасибо за это предложение. Я сделал так, как вы сказали, и использование памяти во время этой операции снизилось примерно на 75%, без необходимости реструктурировать мои данные или сохранить их в другом месте. –

1

Возможно, существует большая разница в размере между вашими объектами «Поиск» и соответствующими изображениями. Таким образом, ваша основная цель должна заключаться в том, чтобы переконфигурировать вашу базу данных таким образом, чтобы неспособность (загрузка) объекта Finding не загружала автоматически кодированное изображение с базой 64.

Это на самом деле одна из основных сильных сторон данных кода: загрузка части иерархии объектов. Просто попробуйте переместить кодированные данные base64 в собственный (управляемый) объект, чтобы Core Data не загружал его. Он будет по-прежнему загружаться по мере необходимости, когда ссылка будет затронута.

 Смежные вопросы

  • Нет связанных вопросов^_^