Swift 处理大型UIImage阵列时出现内存问题
我在一个数组中存储了大约100个Swift 处理大型UIImage阵列时出现内存问题,swift,memory,memory-management,uiimage,Swift,Memory,Memory Management,Uiimage,我在一个数组中存储了大约100个UIImage。我知道有一个内存使用问题最终会导致应用程序崩溃,特别是在旧设备(iPhone 4s)上。就用户体验而言在文档目录中存储所有ui图像——不是一个选项(需要太长时间)。所以我想“合并”这两种方法。等待,直到收到内存使用警告,停止将图像保存到阵列,然后开始通过磁盘存储。我找不到正确的方法来处理内存泄漏/警告/使用呼叫 override func didReceiveMemoryWarning() { super.didReceiveMe
UIImage
。我知道有一个内存使用问题最终会导致应用程序崩溃,特别是在旧设备(iPhone 4s)上。就用户体验而言在文档目录
中存储所有ui图像
——不是一个选项(需要太长时间)。所以我想“合并”这两种方法。等待,直到收到内存使用警告,停止将图像保存到阵列,然后开始通过磁盘存储。我找不到正确的方法来处理内存泄漏/警告/使用呼叫
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
print("memory warning")
}
当我在真正的设备上测试时,它只是崩溃——没有调用方法。有什么建议吗?尝试使用图像缓存库。 最受欢迎的比较如下: 我的经验:SDWebImage最适用于通常来自互联网的URL来源的图像,而Haneke最适用于基于ID的图像,例如视频生成的缩略图。 这两种都有椰子荚
SDWebImage使用CoreData SQLite DB进行URL缓存。它没有“手工制作”图像的方法,但在从互联网下载图像的REST应用程序中,它在世界范围内非常流行。我正在使用刚刚发布在AppStore MyHairDressers应用程序中的。FastCache使用文件进行URL缓存。但它也像SDWebImage一样,不适合缓存“手工制作”的图像。两者都非常适合通过URL下载的图像。Haneke不仅可以通过URL,还可以通过自定义ID存储图像。但与FastCache一样,它需要一些配置。以下是一些配置的代码: `` `` 下面是创建缓存图像的示例(TableViewCell包含带有缩略图的CollectionView): `` `` 并使用(表视图单元格中集合的集合视图单元格): ``
``我认为,如果你遇到这样的问题,要么降低图像质量,要么让它们等待应用程序写入磁盘。嘿@GabrielJones。不幸的是我不能。由于我的应用程序需要,它们应该同时存在。换言之,我不能把这组人分开。@GabrielJones,实际上我把质量降低了近60%(这甚至比我需要的还要少)。一个很好的问题可能是,在质量/字节测试方面,调整图像大小的最有效方法是什么?看看这个:虽然是在Obj-c中…也看看这个:谢谢,我会检查的!SDWebImage使用CoreData SQLite DB进行URL缓存。它没有“手工制作”图像的方法,但在从互联网下载图像的REST应用程序中,它在世界范围内非常流行。我在AppStore my Hairdressers应用程序中刚刚发布的应用程序中使用了它。我知道它对于在线获取非常有用,尽管我使用的是本地创建的图像。我需要让它们保持一定程度的缓存,至少要填充缓存,并且只存储它们。我在上面的回答中添加了一些代码示例,对不起,关于ObjC,关于“手工制作”不是网络来源的图片,谢谢Alexey提供了一个非常有用的答案。我会深入调查的!
HNKCacheFormat *cacheFormatThumbnail = [[HNKCache sharedCache] formats][CACHE_FORMAT_THUMBNAIL];
if (cacheFormatThumbnail == nil)
{
cacheFormatThumbnail = [[HNKCacheFormat alloc] initWithName:CACHE_FORMAT_THUMBNAIL];
cacheFormatThumbnail.size = CGSizeMake(100.0f, 56.0f);
cacheFormatThumbnail.scaleMode = HNKScaleModeAspectFit;
cacheFormatThumbnail.compressionQuality = 0.5f;
cacheFormatThumbnail.diskCapacity = 10 * 1024 * 1024; // 10MB
cacheFormatThumbnail.preloadPolicy = HNKPreloadPolicyLastSession;
[[HNKCache sharedCache] registerFormat:cacheFormatThumbnail];
}
HNKCacheFormat *cacheFormatPhoto = [[HNKCache sharedCache] formats][CACHE_FORMAT_PHOTO];
if (cacheFormatPhoto == nil)
{
cacheFormatPhoto = [[HNKCacheFormat alloc] initWithName:CACHE_FORMAT_PHOTO];
CGFloat scale = [[UIScreen mainScreen] scale];
cacheFormatPhoto.size = CGSizeMake(1280.0f * scale, 720.0f * scale);
cacheFormatPhoto.scaleMode = HNKScaleModeAspectFit;
cacheFormatPhoto.compressionQuality = 0.5f;
cacheFormatPhoto.diskCapacity = 50 * 1024 * 1024; // 50MB
cacheFormatPhoto.preloadPolicy = HNKPreloadPolicyNone;
[[HNKCache sharedCache] registerFormat:cacheFormatPhoto];
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VideoCell *cell = (VideoCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath];
VideoAsset *asset = (VideoAsset *)[self.fetchedResultsController objectAtIndexPath:indexPath];
if ([asset thumbnails] == 0)
{
MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:[cell thumbnails]];
hud.removeFromSuperViewOnHide = YES;
[[cell thumbnails] addSubview:hud];
hud.labelText = NSLocalizedString(@"H11",nil);
[hud show:YES];
CGFloat scale = [[UIScreen mainScreen] scale];
CGSize size = CGSizeMake(100.0f * scale, 56.0f *scale);
__weak typeof(cell) weakCell = cell;
[asset generateThumbnails:self->thumbnailsCount offset:self->thumbnailsOffset size:size completion:^(NSArray *thumbnails) {
dispatch_async(dispatch_get_main_queue(), ^{
[hud hide:YES];
});
if ((thumbnails != nil) && ([thumbnails count] > 0))
{
HNKCache *cache = [HNKCache sharedCache];
NSUInteger n = 0;
NSUInteger keyHash = [[[asset assetURL] absoluteString] hash];
for (UIImage *image in thumbnails)
{
[cache setImage:image forKey:[NSString stringWithFormat:@"%lu@%i",(unsigned long)keyHash,(int)(n++)] formatName:CACHE_FORMAT_THUMBNAIL];
dispatch_async(dispatch_get_main_queue(), ^{
if (weakCell != nil)
{
__strong typeof(cell) strongCell = weakCell;
[[strongCell thumbnails] reloadData];
}
});
formatName:CACHE_FORMAT_PHOTO];
}
}
}];
}
return (UITableViewCell *)cell;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ThumbnailCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
NSString *key = [NSString stringWithFormat:@"%lu@%i",(unsigned long)[[[(VideoAsset *)self->_selectedObject assetURL] absoluteString] hash],(int)[indexPath item]];
[cell setKey:key];
[cell setTag:[indexPath item]];
__weak typeof(cell) weakCell = cell;
[[HNKCache sharedCache] fetchImageForKey:key formatName:CACHE_FORMAT_THUMBNAIL success:^(UIImage *image) {
[[weakCell image] setImage:image];
} failure:^(NSError *error) {
if ([[error domain] isEqualToString:HNKErrorDomain] && ([error code] == HNKErrorImageNotFound))
{
[[weakCell image] setImage:[UIImage imageNamed:@"movieplaceholder"]];
}
else [error reportError];
}];
return cell;
}