Я разгадал тайну - и я уверен, что это ошибка со стороны Apple.
Как предложил Кендалл (спасибо!), Проблема заключается в том, как InterfaceBuilder загружает изображения из файла NIB. Когда вы initFromNib, все UIImageViews будут инициироваться с UIImage, используя imageNamed: метод UIImage. Этот вызов использует кэширование для изображения. Обычно это то, что вы хотите. Однако с очень большими изображениями и, кроме того, изображениями, которые прокручиваются далеко от видимой области, кажется, что они не подчиняются предупреждениям памяти и не сбрасывают этот кэш. Это то, что я считаю ошибкой на стороне Apple (пожалуйста, прокомментируйте, если вы согласны / не согласны - я хотел бы представить это, если другие согласятся). Как я сказал выше, память, используемая этими изображениями, кажется, освобождается, если пользователь прокручивает достаточно, чтобы все это было видно.
Обходной путь, который я нашел (также предложение Кендалла), - оставить имя изображения пустым в файле NIB. Таким образом, вы выкладываете свои элементы UIImageView как обычно, но не выбираете изображение. Затем в своем коде viewDidLoad вы входите и загружаете изображение, используя вместо этого imageWithContentsOfFile :. Этот метод НЕ кэширует изображение и, следовательно, не вызывает проблем с памятью при сохранении больших изображений.
Конечно, imageNamed: намного проще в использовании, потому что он по умолчанию используется в пакете, а не в поиске пути. Однако вы можете получить путь к пакету с помощью следующего:
NSString *fullpath = [[[NSBundle mainBundle] bundlePath];
Сложив все это вместе, вот как это выглядит в коде:
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:[NSString stringWithFormat:@"/%@-%d.png", self.nibName, imageView.tag]];
UIImage *loadImage = [UIImage imageWithContentsOfFile:fullpath];
imageView.image = loadImage;
Итак, добавляя это к моему коду выше, полная функция выглядит так:
- (CGFloat)findHeight
{
UIImageView *imageView = nil;
NSArray *subviews = [self.scrollView subviews];
CGFloat maxYLoc = 0;
for (imageView in subviews)
{
if ([imageView isKindOfClass:[UIImageView class]])
{
CGRect frame = imageView.frame;
if ((frame.origin.y + frame.size.height) > maxYLoc) {
maxYLoc = frame.origin.y;
maxYLoc += frame.size.height;
}
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:[NSString stringWithFormat:@"/%@-%d.png", self.nibName, imageView.tag]];
NSLog(fullpath);
UIImage *loadImage = [UIImage imageWithContentsOfFile:fullpath];
imageView.image = loadImage;
}
}
return maxYLoc;
}