内存泄漏 - UIImagePNGRepresentation

2024-04-01

我正在尝试复制图像UIImagePicker到文档目录。我在用@"UIImagePickerControllerOriginalImage"key 从 UIImagePickerDelegate 的字典中获取原始图像。我正在使用将图像写入文件UIImagePNGRepresentation。当我添加(重复该过程)高分辨率图像(图像大小约为 20 mb)时,我面临内存问题。

我分析并使用了 Xcode 的内存泄漏功能,它放大了下面一段代码,该代码是造成泄漏的原因。

@autoreleasepool {
    imagesData = UIImagePNGRepresentation(images);
    [imagesData writeToFile:name atomically:NO];
    imagesData = nil;
    //[UIImageJPEGRepresentation(images, 1.0) writeToFile:name atomically:YES];
}

我在这里看到了很多关于内存泄漏的问题UIImagePNGRepresentation。但我还没有找到解决我的问题的正确方法。需要帮忙。


我不知道有任何“泄漏”UIImagePNGRepresentation,但这确实是对内存的过度使用,但这里有几个问题:

  1. 首先,通过a往返原始资产的过程UIImage然后使用UIImagePNGRepresentation()效率相当低,最终可能会得到NSData这比原始资产大得多。例如,我选择了一张原始资源为1.5mb的照片,UIImageJPEGRepresentation (with compressionQuality为 1.0) 为 6mb,并且UIImagePNGRepresentation()大约10mb。 (这些数字可能因图像而异,但您已经了解了基本概念。)

    您通常可以通过使用来缓解此问题UIImageJPEGRepresentation with a compressionQuality小于 1.0(例如 0.8 或 0.9 提供最小的图像质量损失,但仍可观察到NSData地点)。但这是有损压缩。此外,在此过程中您会丢失一些图像元数据。

  2. 我相信您同时在内存中保存了同一图像的多个副本:您同时拥有UIImage代表以及NSData object.

  3. 不仅是NSData如果资产的表示大于所需的大小,您还会将整个资产一次性加载到内存中。这是没有必要的。

相反,您可能会考虑从流式传输原始资源ALAssetLibrary直接写入持久内存,无需使用UIImagePNGRepresentation or UIImageJPEGRepresentation,并且无需将其加载到UIImage根本不。相反,创建一个小缓冲区,通过以下方式重复用原始资源的部分填充此缓冲区getBytes,使用以下命令将这个小缓冲区写入临时文件NSOutputStream当你继续前进时。您可以重复该过程,直到将整个资产写入持久存储。该过程的总内存占用量比其他方法低得多。

例如:

static NSInteger kBufferSize = 1024 * 10;

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSURL *url = info[UIImagePickerControllerReferenceURL];

    [self.library assetForURL:url resultBlock:^(ALAsset *asset) {
        ALAssetRepresentation *representation = [asset defaultRepresentation];
        long long remaining = representation.size;
        NSString *filename  = representation.filename;

        NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
        NSString *path = [documentsPath stringByAppendingPathComponent:filename];
        NSString *tempPath = [self pathForTemporaryFileWithPrefix:@"ALAssetDownload"];

        NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:tempPath append:NO];
        NSAssert(outputStream, @"Unable to create output stream");

        [outputStream open];
        
        long long representationOffset = 0ll;
        NSError *error;

        uint8_t buffer[kBufferSize];

        while (remaining > 0ll) {
            NSInteger bytesRetrieved = [representation getBytes:buffer fromOffset:representationOffset length:sizeof(buffer) error:&error];
            if (bytesRetrieved < 0) {
                NSLog(@"failed getBytes: %@", error);
                [outputStream close];
                [[NSFileManager defaultManager] removeItemAtPath:tempPath error:nil];
                return;
            } else {
                remaining -= bytesRetrieved;
                representationOffset += bytesRetrieved;
                [outputStream write:buffer maxLength:bytesRetrieved];
            }
        }

        [outputStream close];
        
        if (![[NSFileManager defaultManager] moveItemAtPath:tempPath toPath:path error:&error]) {
            NSLog(@"Unable to move file: %@", error);
        }

    } failureBlock:^(NSError *error) {
        NSLog(@"assetForURL error = %@", error);
    }];
}

- (NSString *)pathForTemporaryFileWithPrefix:(NSString *)prefix
{
    NSString    *uuidString = [[NSUUID UUID] UUIDString];

    // If supporting iOS versions prior to 6.0, you can use:
    //
    // CFUUIDRef uuid = CFUUIDCreate(NULL);
    // assert(uuid != NULL);
    // NSString *uuidString = CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
    // CFRelease(uuid);
    
    return [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-%@", prefix, uuidString]];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存泄漏 - UIImagePNGRepresentation 的相关文章

  • 在 iOS 上使用 Web 服务的最佳方式?

    我想构建一个 iOS 应用程序 让您登录到网络服务 之后 应用程序将 当用户选择时 通过 https 发送登录名 密码以及请求的变量 例如 在请求 新闻更新 后 它将收到 XML 格式的请求信息 类似于
  • Swift Codable 将空 json 解码为 nil 或空对象

    这是我的代码 class LoginUserResponse Codable var result String var data LoginUserResponseData var mess String public class Log
  • 当 UITextField 已满或空时显示警报 Swift

    下面的代码中 如果 userNameTF 或 passwordTF 已满或为空 则会显示警报 IBAction func LoginBtn sender AnyObject let userName userNameTF text let
  • 为什么我不能在 Realm 属性上使用 private

    我正在尝试在 RealmSwift 中存储一个枚举案例 但 Realm 不支持枚举 本文 https medium com it works locally persisting swift enumerations with realm
  • 在iOS上,“添加到主页”缓存保存在哪里,如何清除它?

    我正在 iPad iOS v7 上制作一个 html5 游戏 当我将其添加到主页时 它非常顽固地释放缓存 如果我在 Safari 中查看它 这会按照您所期望的方式工作 如果我刷新一次或两次 页面就会以最新状态缓存 但在主页上却是另一回事 它
  • 如何在 iOS 中更改部分透明图像的颜色?

    我有一个具有部分透明度的单色图像 我有正常版本和 2X 版本的图像 我希望能够用代码将图像着色为不同的颜色 下面的代码适用于普通图像 但 2X 最终会出现伪影 正常图像可能有类似的问题如果是这样 由于分辨率的原因我无法检测到它 UIImag
  • iOS 滚动视图允许滚动过去的内容

    我正在努力优化我的应用程序以适应横向和较小的屏幕 我主要使用滚动视图来实现这一点 在我的其中一个视图中 我有一个容器视图 当我在故事板中的设备之间切换时 这个容器视图看起来很完美 容器视图映射到具有滚动视图的视图控制器 该滚动视图的顶部 底
  • 使用 Interface Builder 创建 UIScrollView 的步骤

    我正在尝试使用 UIScrollView 但似乎有一些基本的事情我不理解 假设我想在我的 iPhone 应用程序中使用 UIScrollView 我有一个充满按钮的视图 尺寸为 320x700 显然 这对于 320x480 的 iPhone
  • 添加自定义过渡会导致 xib 加载错误的屏幕尺寸

    我正在尝试向具有 xib 的 UIViewController 添加自定义过渡 我尝试了几种方法 但它们都有相同的问题 视图显示的屏幕尺寸错误 我当前的示例基于以下教程 使用 Swift 在 iOS 中自定义 UIViewControlle
  • iOS 中的构建对象文件扩展名是什么?

    当我在项目中构建java对象类时 将创建带有 class扩展名的构建文件 并且人类不可读 快速构建文件怎么样 example car java gt build gt car class 构建后会是什么 car swift gt build
  • 应用内购买产品禁用“提交审核”

    基于此处提到的所有步骤http troybrant net blog 2010 01 in app purchases a full walkthrough http troybrant net blog 2010 01 in app pu
  • 当强制退出/向上滑动以终止 iOS 应用程序而不点击横幅/警报时,如何获取推送通知有效负载?

    我正在构建一个应用程序来处理从 Parse 推送的通知 并尝试创建通知历史记录功能 我已经成功启用了后台模式 因此当应用程序在后台运行时 应用程序可以通过以下方式很好地获取有效负载application didReceiveRemoteNo
  • 频繁绘制 CGPath 时的性能

    我正在开发一个将数据可视化为折线图的 iOS 应用程序 该图被绘制为CGPath在全屏自定义中UIView最多包含 320 个数据点 数据经常更新 图表需要相应地重新绘制 刷新率为 10 秒就很好了 到目前为止很容易 然而 我的方法似乎需要
  • 使用 MFMailComposeViewController 类从 iPhone 应用程序发送带有 IMG 标签的 HTML 电子邮件

    我正在使用 MFMailComposeViewController 类从我的 iPhone 应用程序发送格式化的 HTML 电子邮件 我需要在电子邮件中包含图像 并且我在电子邮件正文中添加了 IMG 标签 IBAction shareWit
  • iOS 循环对象的属性并添加操作

    我有一个具有几个类似属性的类 UISliders 我想添加用户开始和结束使用每个滑块时的操作 每个滑块都将链接到同一个选择器 因此我考虑只是迭代它们 而不是编写 10 个几乎相同的代码块 问题是 最有效的方法是什么 我尝试过这样的事情 在运
  • 填充 CoreData 创建的 sqlite 数据库

    我有一个由 CoreData 模型自动创建的 sqlite DB 但我的应用程序不会让用户能够将数据写入其中 而是我想用程序所需的所有数据预先填充它 我的问题是 CoreData 创建的 sqlite DB 具有未知的表和字段 这些表和字段
  • 苹果企业程序分发问题[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 这个问题涉及到Apple iOS 开发者企业计划 http developer apple com programs ios enterprise 我
  • 苹果推送通知在生产中不起作用

    我们完全陷入困境 请帮忙 我和我的团队制作了一个 iPhone 应用程序 这是我们第一次在 iOS 上尝试 一切都很好 直到我们提交应用程序并在应用程序商店上可用为止 推送通知服务无法正常工作 我在网上搜索并尝试根据人们的建议仔细检查我们的
  • IPV6 快速可达性

    我是 swift 和 xcode 的新手 并且我的应用程序因 IPV6 而被拒绝 性能 2 1 当我们执行以下操作时 您的应用程序会在运行 iOS 9 3 5 并连接到 IPv6 网络的 iPad 和 iPhone 上崩溃 具体来说 当我们
  • CGImage/UIImage 在 UI 线程上延迟加载会导致卡顿

    我的程序显示一个水平滚动表面 从左到右平铺有 UIImageViews 代码在 UI 线程上运行 以确保新可见的 UIImageView 分配有新加载的 UIImage 加载发生在后台线程上 一切工作几乎都很好 除了每个图像变得可见时出现口

随机推荐

  • 标记文本解析器,如 Objective-C 中的 stackoverflow 格式化程序

    我正在使用 Objective C 创建标记编辑器 我需要以下功能 识别块的分界 例如 block 删除开始和结束 标签 例如 下一个文本是 bold 变为 下一个文本为粗体 确定新上下文中标记文本的开始和结束位置 下一个文本是粗体 编辑
  • 多种类型实体的数据库设计

    我需要开发一个应用程序 其中有 4 种类型的用户实体 管理员 合作伙伴 公司和客户 每种用户类型都有自己的一组详细信息 并且他们都应该能够执行常见操作 例如发送消息 付款等等 这些操作应保留在单个表中 但它们需要引用确切的用户 无论其类型如
  • Jasper Report 中的 Java Beans 列表中的 pass 列表

    我正在使用 Jasper Report 和 Servlet Bean 团队看起来像 private int tid private String title private List
  • HornetQ JMSException:无法创建会话工厂

    我正在尝试直接实例化 JMS 资源 而不使用远程 HORNETQ 的 JNDI 我正在 Eclipse IDE 中运行我的测试代码 设置我的类路径以使用 HornetQ 2 2 5 库 目标HornetQ是版本2 1 2 Final 我认为
  • 如何使用 C# 检索 .config 文件中的自定义配置部分列表? [复制]

    这个问题在这里已经有答案了 当我尝试使用检索 config 文件中的部分列表时 Configuration config ConfigurationManager OpenExeConfiguration ConfigurationUser
  • c#/.Net Socket.Shutdown

    我认识到此类问题已有很长的历史 但我使用此问题的方式必须是正确的 net 方式 但它似乎不起作用 我有一个简单的同步 IP 服务器守护进程 它执行一个简单的 AcceptSocket 执行一些操作 socket send socket sh
  • 如何在 jQuery 中发送 PUT/DELETE 请求?

    GET get POST post 关于什么PUT DELETE 你可以使用ajax http docs jquery com Ajax jQuery ajax options method ajax url script cgi type
  • 将 axios POST 请求与 moxios 匹配

    是否可以使用 moxios 模拟对 POST 请求的回复 不仅通过 URL 匹配 还通过 POST 正文匹配 事后检查尸体对我来说也很有用 这就是我现在正在做的事情 据我所知 没有特定于方法的存根方法 describe createCode
  • 应该创建多种文档类型或多个索引吗?

    我们为企业托管许多网站 每个企业都会有许多他们可能希望通过 ES 进行索引和搜索的文档类型 通常 每个业务拥有的文档类型数量少于 20 个 每个类型可能拥有少于 100k 个文档 通常要少得多 我不确定应该如何设置这些网站的数据 我应该将它
  • ice_cube 的营业时间

    我如何能够在单一时间表中规定餐厅的营业时间 周一至周五 8 点至 16 点非常简单 schedule Schedule new Time parse Date yesterday to s 8 00 duration gt 60 60 8
  • MVC 4 和 JsonResult 格式

    这段代码的结果格式有问题 public JsonResult getCategorias int id var res from c in db Categorias where id HasValue c CategoriaPadre i
  • 水平和垂直并排有许多小 div 和一个大 div?

    我应该如何创建这种结构 我的第一个想法是将四个粉红色组合成一个橙色 这样我就得到了 4pinksVS1orange 现在下一个难题是将它们并排放置 我不知道 好吧 我知道一些 hxcks 但它们很容易被打破 然后 拼图是底行有四个粉红色的拼
  • 浏览器中文本区域处理不一致

    这是我在下面提供的标记中看到的内容 没有一个浏览器将文本区域保留在容器中 这很不方便 但并不是什么大问题 然而 令人烦恼的是 无论我做什么 我都无法摆脱 Chrome 中文本区域的下边距 有什么建议么 Here is everything
  • JavaScript - 模拟单击​​上下文菜单

    我正在尝试为网站创建网络自动化 我正在模拟点击 通常我会向如下所示的元素添加 ID 并使用 Chrome 开发者控制台触发单击 并且它始终有效 p s 下面的问题已经过时了 我实际上正在尝试从 web whatsapp com 的上下文菜单
  • PyInstaller ImportError:没有名为“pyfiglet.fonts”的模块

    我正在尝试使用 PyInstaller 编译 Asciimatics 的演示脚本之一 希望最终能够为我正在开发的基于文本的游戏创建一个简单的 GUI 它返回以下错误 C Users X Documents Python Scripts as
  • 使用 DoubleClick“无法加载广告:3”

    我正在使用 DoubleClick 在 Android 应用程序中设置广告 但无法显示最终的广告 有人能帮我吗 当我通过添加 addTestDevice xxx 来测试广告时 我得到了测试广告 但是当我删除此行时 出现以下错误 W 广告 广
  • 隐藏 Woocommerce 订阅价格中的“免费试用”文本,但保留注册费

    问题的第一部分 隐藏 Woocommerce 订阅价格中的 免费试用 文本 在这篇很棒的帖子中得到了回答 隐藏 Woocommerce 订阅价格中的 免费试用 文本 https stackoverflow com questions 489
  • 隐藏滚动条(启用滚动)

    我有一个包含 2 列和多行的表 table border 0 tr td something td td div class bubble div td tr tr td something1 td td div class bubble
  • OpenCV (cv2) 中的 unactorPoints 与 Python 错误结果

    我尝试纠正图像和该图像上的一些点 校正图像效果非常好 这部分代码不是我提供的 mapx mapy cv2 initUndistortRectifyMap camera matrix dist coefs np array 1 0 0 0 1
  • 内存泄漏 - UIImagePNGRepresentation

    我正在尝试复制图像UIImagePicker到文档目录 我在用 UIImagePickerControllerOriginalImage key 从 UIImagePickerDelegate 的字典中获取原始图像 我正在使用将图像写入文件