jjzjj

ios - iOS 设备上图像的内存管理性能不佳

coder 2023-09-27 原文

我有以下问题:

我有一个主视图对象(继承自 UIView),它以 4x4 布局显示 16 个正方形的网格(每个都是我创建的继承自 UIImageView 的类)。

这 16 个正方形中的每一个都是 160x160,并且包含一个不超过 30kb 的图像(每个正方形不同的图像)。然而,该图像是 500x500(因为它在程序的其他地方使用,以其全尺寸显示),因此它在“方形”类中通过 setFrame 方法调整为 160x160。

通过查看应用程序运行时 Xcode 的内存管理功能,我注意到了一些事情:

  1. 将这些方 block 中的每一个添加到主视图对象后,应用程序的内存使用量都会增加 1MB。这不会在实例化时发生,而只会在它们被 [self addSubview:square] 添加到主视图对象时发生。
  2. 如果我对所有方 block 使用相同的图像,内存增加是 最小的。如果我初始化没有任何图像的方形对象,那么 增幅基本为零。
  3. 同一个应用程序,在模拟器中运行时,使用了 1/6 的内存 它在实际设备上运行。

这里的重点是:为什么在加载 30kb 图像时每个方 block 都占用 1MB 内存?有没有办法减少这个?我尝试过以多种不同的方式创建图像:[UIImage imageNamed:img][UIImage imageWithContentsFromFile:path][UIImage imageWithData:imgData scale:scale],以及不调整框架的大小。

最佳答案

当您在较小的 UIImageView 中使用 500x500 图像时,它仍会将较大的图像加载到内存中。您可以通过调整 UIImage 本身(不仅仅是调整 UIImageViewframe)来解决这个问题,制作一个 160x160 的图像,然后使用它在您的 View 中的图像。参见 this answer对于一些调整图像大小的代码,可以按如下方式调用:

UIImage *smallImage = [image scaleImageToSizeAspectFill:CGSizeMake(160, 160)];

您甚至可能想要保存调整大小后的图像,这样您就不会一直为每次创建较小图像的计算开销所累,例如:

NSData *data = UIImagePNGRepresentation(smallImage);
[data writeToFile:path atomically:YES];

然后您可以在以后调用 View 时加载与您的小图像相对应的 PNG 文件。


在回答你为什么占用这么多内存的问题时,这是因为虽然图像可能以压缩的 JPG 或 PNG 格式存储在持久存储中,但我怀疑它在内存中是作为未压缩的位图保存的。有许多内部格式,但常见的一种是 32 位格式,红色、绿色、蓝色和 alpha 各有 8 位。不管具体细节如何,您都可以快速了解 500 x 500 像素表示(每个像素 4 个字节)如何转换为 1 MB 内存。但是一张 160 x 160 的图片应该大约是原来的十分之一。

关于ios - iOS 设备上图像的内存管理性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19040285/

有关ios - iOS 设备上图像的内存管理性能不佳的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  8. ruby-on-rails - 禁用设备的 :confirmable on-the-fly to batch-generate users - 2

    Devise是一个Ruby库,它为我提供了这个User类:classUser当写入:confirmable时,注册时会发送一封确认邮件。上周我不得不批量创建300个用户,所以我在恢复之前注释掉了:confirmable几分钟。现在我正在为用户批量创建创建一个UI,因此我需要即时添加/删除:confirmable。(我也可以直接修改Devise的源码,但我宁愿不去调和它)问题:如何即时添加/删除:confirmable? 最佳答案 WayneConrad的解决方案:user=User.newuser.skip_confirmation

  9. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  10. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

随机推荐