Приложение, над которым я работаю, относительно простое, но оно выдает предупреждения памяти. Я пытаюсь выяснить, нужно ли дизайну приложения слишком много памяти, и его следует переписать и разбить, чтобы использовать меньше, или дизайн приложения в порядке, но само приложение раздуто и неправильно сжимает больше памяти, чем необходимо.
Приложение загружает из Интернета XML-файл, содержащий набор вопросов, а затем генерирует UIScrollView, который отображает список элементов управления вопросами. Каждый элемент управления вопросом имеет UITextView и UISegmentedControl, UIButton, UITableView, UITextField или четыре UITextFields с UIButton (пользовательский элемент управления датой). Вот скриншот:
Эта установка прекрасно работает для небольших наборов вопросов, но приложение начинает выдавать предупреждения памяти с большими наборами более 120 вопросов. Вот типичный прогон с распределениями и инструментами VM Tracker на большем наборе:
Пик памяти Allocations при загрузке xml и загрузке модели, но предупреждения не выдаются до тех пор, пока память Allocations не загрузится. Хотя память VM Tracker все еще увеличивается, когда они выбрасываются, это заставляет меня думать, что элементы управления все еще загружаются в память, и что VM Tracker является лучшим индикатором роста памяти, вызывающего предупреждения. Обычно предупреждения появляются, когда размер резидента становится больше 125 МБ.
Я нашел один способ значительно уменьшить размер резидента. Элементы управления вопросом имеют пользовательское представление, чтобы дать им закругленные края и тень. Если я закомментирую код drawRect (показанный ниже) из пользовательского представления, память Allocations останется прежней, но Resident Size уменьшится примерно на 30 МБ и не превысит 93 МБ. Я могу найти более светлый фон для вопросов, но я бы предпочел сохранить закругленные края и тень, если смогу уменьшить объем памяти.
- (void)drawRect:(CGRect)rect {
// get the contect
CGContextRef context = UIGraphicsGetCurrentContext();
//for the shadow, save the state then draw the shadow
CGContextSaveGState(context);
CGContextSetShadow(context, CGSizeMake(4,-5), 10);
//now draw the rounded rectangle
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
if(_HighlightColor==nil){
_HighlightColor = [[UIColor whiteColor] retain];
}
CGContextSetFillColorWithColor(context, _HighlightColor.CGColor);
//since I need room in my rect for the shadow, make the rounded rectangle a little smaller than frame
CGRect rrect = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetWidth(rect)-30, CGRectGetHeight(rect)-30);
CGFloat radius = 5;
// the rest is pretty much copied from Apples example
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
// Start at 1
CGContextMoveToPoint(context, minx, midy);
// Add an arc through 2 to 3
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
// Add an arc through 4 to 5
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
// Add an arc through 6 to 7
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
// Add an arc through 8 to 9
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
// Close the path
CGContextClosePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
//for the shadow
CGContextRestoreGState(context);
}
Приборы и предупреждения памяти создают впечатление, что память исчерпана, но эти цифры кажутся мне высокими. Я бы не подумал, что 120 из этих элементов управления вопросами в виде прокрутки будут проблемой для iPad, но у меня нет ориентира относительно того, сколько памяти они должны использовать. Учитывая некоторые графически интенсивные игры, которые может запускать iPad, не похоже, что простой код drawRect, приведенный выше, потребляет более 30 МБ в элементах управления вопросом. Это потребление памяти кажется высоким или это то, что вы ожидаете от приложения с таким количеством простых элементов пользовательского интерфейса? Есть ли в drawRect что-то, что могло бы поглотить много памяти или какие-либо предложения по его оптимизации? Если кажется, что это должно максимально увеличить память iPad, я буду создавать вкладки или страницы и ограничивать количество вопросов, которые я задаю на вкладку / страницу, так что только часть элементов управления будет загружена в память одновременно. Однако я бы не стал разбивать их, если бы iPad мог обрабатывать их все в памяти. Любой вклад приветствуется.