Обработка ошибок памяти в iPhone

Я хотел бы обрабатывать ошибки нехватки памяти в iPhone, чтобы выполнять логику с меньшими требованиями к памяти в случае, если я запускаю память. В частности, я хотел бы сделать что-то очень похожее на следующий псевдокод:

UIImage* image;
try  {
    image = [UIImage imageNamed:@"high_quality_image.png"];
} catch (OutOfMemoryException e) {
    image = [UIImage imageNamed:@"low_quality_image.jpg"];
}

Сначала я пытаюсь загрузить изображение высокого качества, и если при этом у меня заканчивается память, я использую изображение более низкого качества.

Возможно ли это? Есть ли какое-то исключение или уведомление, которое можно обработать при возникновении ошибки нехватки памяти?

Предупреждение о нехватке памяти — это не то, что мне нужно, так как оно получено до того, как в телефоне заканчивается память. Я хотел бы знать, не сработала ли логика, которую я выполняю, из-за ошибки нехватки памяти, и справиться с этим соответствующим образом.

Кроме того, что-то вроде этого также может помочь:

UIImage* image;
if (enoughMemory) {
    image = [UIImage imageNamed:@"high_quality_image.png"];
} else {
    image = [UIImage imageNamed:@"low_quality_image.jpg"];
}

person hpique    schedule 07.05.2010    source источник


Ответы (3)


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

использование памяти iPhone

person Joo Park    schedule 07.05.2010
comment
Спасибо Джу. Можно ли узнать, сколько памяти у вас осталось? - person hpique; 08.05.2010
comment
возьмите число, полученное из этого кода, и вычтите из 24 мегабайт. Я думаю, что 24 мегабайта — это максимум, который Apple разрешает для каждого запущенного приложения. - person Joo Park; 08.05.2010
comment
Существует ли константа с таким значением? Скорее всего, iPod touch разных поколений, iPhone и iPad не имеют одинакового макс. - person hpique; 09.05.2010

iPhone имеет предупреждение о нехватке памяти, которое срабатывает при достижении определенного порога памяти. Этот обратный вызов выдается приложению, и на него необходимо ответить соответствующим образом, иначе ваше приложение рискует быть вытесненным операционной системой. Тогда вашему приложению было бы полезно преобразовать изображения с большим объемом памяти в изображения с меньшим объемом памяти.

Однако будьте осторожны, так как размер файла на диске не обязательно показывает, сколько памяти он будет потреблять после загрузки и подготовки к использованию на устройстве.

См. здесь для получения дополнительной информации об обработке предупреждений о нехватке памяти.

person fbrereto    schedule 07.05.2010
comment
Спасибо за быстрый ответ. Это было бы немного по-другому. Предупреждение о нехватке памяти вызывается до того, как в телефоне закончится память, и я могу освободить память, если это необходимо. В этом случае я хочу знать, не сработала ли логика, которую я выполняю, из-за нехватки памяти. - person hpique; 07.05.2010
comment
Вы пробовали довести устройство до предела памяти предложенным вами способом? Я думаю, что то, как он отвечает, будет определять шаги, которые вы должны предпринять, чтобы получить поведение, которое вы ищете. - person fbrereto; 07.05.2010
comment
Запрос на большой объем памяти просто убивает приложение? Это звучит немного хардкорно. Возможно, возникло исключение или какое-то другое необработанное уведомление? Что-нибудь выводится на консоль, когда это происходит? - person fbrereto; 07.05.2010
comment
Если такое исключение или уведомление можно обработать, это именно то, о чем я спрашиваю. На консоль выводится: Программа приняла сигнал: «0». - person hpique; 08.05.2010
comment
Это дело не может быть обработано. Единственный шанс, который вы получаете, - это предупреждение о памяти в ваших контроллерах представления. Как только ваше приложение достигнет этой критической точки, ОС все равно убьет его. Вы ничего не можете сделать, кроме как освободить немного памяти, когда система скажет вам об этом. - person Jasarien; 08.05.2010
comment
Я думаю, что ответ Джу Пака - единственный жизнеспособный вариант. - person hpique; 09.05.2010

Редактировать: похоже, это был не совсем ответ на ваш вопрос.


Что вы пытаетесь сделать со своими изображениями? Некоторые действия, такие как сохранение полноразмерного изображения, возвращенного контроллером средства выбора изображений, занимают особенно много памяти.

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

  1. Если позже вам понадобится изображение с высоким разрешением, кэшируйте его на диск.
  2. Все изображения для отображения должны иметь минимальное разрешение, которое вам может сойти с рук.
  3. Когда вам понадобится изображение с высоким разрешением, извлеките его из кеша.
  4. Используйте предупреждения о нехватке памяти в качестве знака для освобождения любых изображений, которые у вас есть в памяти, но не видны.

Теперь возможно, что эта ситуация не будет работать для вас. Чтение и запись больших изображений на диск на iPhone происходит медленно. Если это так, то вам нужно будет следовать совету @fbrereto: загрузите большое изображение, следите за предупреждениями о памяти, и если вы их получите, отбросьте его и загрузите маленькое изображение.

Вы определенно не должны игнорировать предупреждения о памяти, но если вы не ответите на них, это не обязательно приведет к сбою вашего приложения. Мой iPhone 3G будет получать предупреждения о памяти почти каждый раз, когда я получаю изображение с UIImagePickerController, и я ничего не могу с этим поделать.

person kubi    schedule 07.05.2010
comment
Я не игнорирую предупреждения памяти. Я всегда освобождаю ресурсы, когда я их получаю. Но иногда мне все равно не хватает памяти, и я хотел бы разобраться и с этим случаем. - person hpique; 08.05.2010