Я создаю приложение, в котором есть несколько разных разделов, и все они довольно объемные. Это связано с веб-сайтом моего клиента, и они представляют собой одежду «высокого дизайна».
Одна часть приложения - это изображения, загруженные с камеры или библиотеки, и табличное представление, которое показывает сетку миниатюр. Достаточно надежно, когда я имею дело с версией UIImagePickerControl для камеры, я получаю удар по нехватке памяти. Если я какое-то время прыгаю вокруг этой части приложения, я время от времени и неповторимо вырываюсь с «status: 10 (SIGBUS)» в отладчике.
При предупреждении о нехватке памяти мой контроллер корневого представления для этого аспекта приложения переходит к моему единственному объекту управления данными, перемещается по массивам кэшированных данных и убивает самый большой фрагмент - изображение, связанное с каждой записью. Thusly:
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Low Memory Warning"
message:@"Cleaning out events data"
delegate:nil
cancelButtonTitle:@"All right then."
otherButtonTitles:nil];
[alert show];
[alert release];
NSInteger spaceSaved;
DataManager *data = [DataManager sharedDataManager];
for (Event *event in data.eventList) {
spaceSaved += [(NSData *)UIImagePNGRepresentation(event.image) length];
event.image = nil;
spaceSaved -= [(NSData *)UIImagePNGRepresentation(event.image) length];
}
NSString *titleString = [NSString stringWithFormat:@"Saved %d on event images", spaceSaved];
for (WondrMark *mark in data.wondrMarks) {
spaceSaved += [(NSData *)UIImagePNGRepresentation(mark.image) length];
mark.image = nil;
spaceSaved -= [(NSData *)UIImagePNGRepresentation(mark.image) length];
}
NSString *messageString = [NSString stringWithFormat:@"And total %d on event and mark images", spaceSaved];
NSLog(@"%@ - %@", titleString, messageString);
// Relinquish ownership any cached data, images, etc that aren't in use.
}
Как вы можете видеть, я делаю (плохую) попытку взглянуть на пространство памяти, которое я освобождаю. Я знаю, что это не говорит мне о фактической памяти самих UIImages, но, по крайней мере, дает мне НЕКОТОРЫЕ числа, так что я вижу, что ЧТО-ТО происходит. (Извините за неудобный способ, которым я создаю это сообщение NSLog - я собирался запустить другой UIAlertView, но понял, что было бы более полезно зарегистрировать его.)
Довольно надежно, после того, как я на некоторое время переключаюсь в части изображения приложения, я открою интерфейс камеры и получу UIAlertView с малым объемом памяти, как три или четыре раза подряд. Вот вывод NSLog за последний раз, когда я его видел:
2010-05-27 08:55:02.659 EverWondr[7974:207] Saved 109591 on event images - And total 1419756 on event and mark images
wait_fences: failed to receive reply: 10004003
2010-05-27 08:55:08.759 EverWondr[7974:207] Saved 4 on event images - And total 392695 on event and mark images
2010-05-27 08:55:14.865 EverWondr[7974:207] Saved 4 on event images - And total 873419 on event and mark images
2010-05-27 08:55:14.969 EverWondr[7974:207] Saved 4 on event images - And total 4 on event and mark images
2010-05-27 08:55:15.064 EverWondr[7974:207] Saved 4 on event images - And total 4 on event and mark images
И вскоре после этого мы получаем выход SIGBUS. Такова ситуация. Теперь мои конкретные вопросы:
Время, когда я вижу это, происходит, когда диафрагма камеры UIPickerView выключается. Я нажимаю кнопку, чтобы сделать снимок, он выполняет анимацию «щелчка», и Instruments показывает мой объем памяти, занимающий от 10 МБ до 25 МБ, и остается там до тех пор, пока изображение не будет доставлено в мой UIViewController, где использование снизится до 10 или 11мб снова. Если мы сделаем это без предупреждения памяти, мы золотые, но, скорее всего, мы не будем. Что я могу сделать, чтобы это не было так дорого?
Во-вторых, у меня включены NSZombies. Правильно ли я понимаю, что это на самом деле препятствует освобождению памяти? Я подвергаю свое приложение нечестной тестовой среде?
В-третьих, есть ли какой-нибудь способ программно получить использование моей памяти? Или хотя бы использование объекта UIImage? Я просмотрел документы и ничего об этом не вижу.