在我的iOS应用中,我有一个启用了分页的UIScrollView。每个页面都显示一个视图(包含多个子视图);任何时候只加载3个“页面” - 当前查看的页面,左侧的一个页面和右侧的页面。加载在后台懒洋洋地完成。该应用正在使用ARC。
每个页面上的视图主要包含一个从Core Data检索的图像。此图像可能很大,因此首先加载缩略图,然后由较大的图像替换。这个较大的图像实际上是数据存储中实际内容的缩小版本 - 不同屏幕需要完整分辨率版本,但对于此图像滚动条,它只需要适合页面。实际存储的图像可能要大得多(对于来自相机的照片,为2448x3264)。请注意,Core Data中的image属性设置为允许外部存储,因此在大多数情况下,它不会存储在SQLite数据库中。
一切“工作正常”:滚动条和图像加载速度快(首先是缩略图,很快就会加大图像),滚动速度很快。根据Instruments的说法,内存使用率也很好 - 直到第11个图像加载时,内存峰值大约5MB;后续加载的图像可能会导致更多的内存峰值(不是每一个,也许每隔一个导致另一个〜5MB的峰值)。没有特定的图像导致尖峰(我已经改变了加载的图像的顺序,它总是第11个)。这个记忆似乎永远不会被释放。
以下是代码片段,其中的图片是在后台加载的:
- (void)loadImageWithCardInstanceObjectId:(NSManagedObjectID *)cardInstanceObjectId
imageIndex:(NSUInteger)imageIndex
withInitialImageHandler:(void (^)(UIImage *image))initialImageHandler
withFinalImageHandler:(void (^)(UIImage *image))finalImageHandler
{
NSManagedObjectContext *tempMoc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
tempMoc.parentContext = [[DataManager sharedInstance] managedObjectContext];
[tempMoc performBlock:^{
CardInstance *ci = (CardInstance *)[tempMoc objectWithID:cardInstanceObjectId];
if (ci.cardInstanceImages.count == 0) {
// no card images, return the default image
dispatch_async(dispatch_get_main_queue(), ^{
initialImageHandler([UIImage imageNamed:@"CardNoImage.png"]);
});
return;
}
// have card images, pick the one according to the passed in index
UIImage *thumbnail = [[ci.cardInstanceImages objectAtIndex:imageIndex] thumbnailRepresentation];
dispatch_async(dispatch_get_main_queue(), ^{
initialImageHandler(thumbnail);
});
// THIS IS THE OFFENDING LINE
UIImage *fullImage = [[ci.cardInstanceImages objectAtIndex:imageIndex] imageRepresentation];
CGSize size = fullImage.size;
CGFloat ratio = 0;
if (size.width > size.height) {
ratio = 240.0 / size.width;
}
else {
ratio = 240.0 / size.height;
}
CGRect rect = CGRectMake(0.0, 0.0, ceilf(ratio * size.width), ceilf(ratio * size.height));
// create the image to display
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0);
[fullImage drawInRect:rect];
UIImage *imageToDisplay = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
finalImageHandler(imageToDisplay);
});
}];
}
在乐器中,分配的负责库/调用者是CoreData + [_ PFRoutines readExternalReferenceDataFromFile:]。
有关为什么会出现此内存峰值的任何想法?感谢