简体   繁体   English

处理许多图像时如何在iPhone上管理内存

[英]How to manage memory on iPhone when handling many images

I have kind of a unique problem in the project I'm working in. What I'm doing is creating sort of a "wall" of scrollable images that are downloaded from a server that our user can flick through on the iPhone. 在我正在从事的项目中,我遇到了一个独特的问题。我正在做的事情是创建可滚动图像的“墙”,这些图像是从服务器下载的,用户可以在iPhone上浏览。 But the problem is we're having trouble coming up with a good memory management plan here. 但是问题是我们在这里提出一个好的内存管理计划很困难。 What we have running right now is a class that subclasses UIImageView that is being used to store every image we download from the server (these images are saved to the app's documents directory though), and then we also add meta data to it (ie description, tags, etc). 我们现在正在运行的是一个继承UIImageView的类,该类用于存储我们从服务器下载的每个图像(尽管这些图像保存到应用程序的文档目录中),然后我们还向其中添加了元数据(即描述) ,标签等)。 We are then storing this in an NSMutableArray that we then loop through with all the images to place them in our wall. 然后,我们将其存储在NSMutableArray中,然后遍历所有图像以将其放置在墙上。 As you would imagine having all these images in memory is an enormous memory hog. 就像您想象的那样,将所有这些图像存储在内存中是一项巨大的工作 We are having a hard time thinking of a way to do this without using this much of memory. 我们很难思考一种无需使用大量内存的方法。 One of the bigger problems that makes it more difficult is that the images, when placed, need to report when being touched. 使其变得更加困难的更大问题之一是图像在放置时需要在触摸时报告。 So I don't think we can just deallocate them after placing them. 因此,我认为我们不能在放置它们后立即对其进行分配。 Have any of you had experience with handling objects of any kind with large size like this and having to do have them at hand to draw to the screen, play, etc? 你们中的任何人是否有处理此类大尺寸物体的经验,并且必须用手将它们吸引到屏幕上,进行游戏等? What type of technique or approach do you suggest? 您建议使用哪种技术或方法? I've read around about CoreData but don't know if this is what I'm looking for. 我已经阅读了有关CoreData的内容,但是不知道这是否是我想要的。 Appreciate any help. 感谢任何帮助。

Here's the main drawing method for reference: 这是供参考的主要绘制方法:

SOLUTION: WWDC Session Video #104! 解决方案:WWDC会议视频#104!

As long as the images come from disk, and read in using one of the UIImage convenience methods, the UIImage will remain backed by the file, and release memory when needed. 只要图像来自磁盘,并使用UIImage便捷方法之一读取, UIImage就会保留文件的支持,并在需要时释放内存。 It will re-read the file when needed as well. 必要时,它将重新读取文件。 This is all just in the UIImage docs btw. 全部都在UIImage文档btw中。

ps. ps。 even when loading an image from the iPhone library, it remains backed by the file (which your app cannot touch). 即使从iPhone库中加载图像,该图像仍受文件支持(您的应用无法触摸)。 The low-res version needed for display is kept as well btw. 显示所需的低分辨率版本也保持不变。 You can clearly see this happening in Instruments. 您可以在Instruments中清楚地看到这种情况。 An open question of me is if this is if camera images are backed by a file as well. 我的一个公开问题是,是否这也是相机图像也由文件支持的问题?

So really, what you need is a system of enqueuing and dequeuing views as they come and go. 因此,实际上,您需要的是一种在视图进出时对视图进行排队和出队的系统。

An easy example you should be looking at is the Photos app that already exists on your iPhone. 您应该查看的一个简单示例是iPhone上已经存在的“照片”应用程序。 Although you might have a million images on your "wall", you can only see so many images at one time on your screen. 尽管您的“墙上”可能有一百万张图像,但您一次只能在屏幕上看到这么多图像。 That means you don't need a million UIImageViews for all of the images on the wall, just the 20 or so that fit onto the screen. 这意味着您不需要一百万个UIImageViews用于墙上的所有图像,只需20个左右即可适合屏幕。

Think of the wall not as a single big view that's available all the time, but instead follow the paradigm laid out by UITableView. 不要将墙视为一直可用的单个大视图,而应遵循UITableView提出的范例。 A UITableView enqueues UITableViewCells as they disappear and (hopefully) the datasource dequeues and reuses those table cells by just changing the information displayed to the one in the new row. 当UITableViewCell消失时,UITableView使UITableViewCell入队,并且(希望)数据源通过仅将显示的信息更改为新行中的信息而使这些表单元出列并重新使用。

You shouldn't have any problems reporting touches on which image is touched (since you can just look at what image is contained in the imageview, or through some other saved property). 报告触摸到哪个图像的触摸应该没有任何问题(因为您可以只查看imageview中包含的图像,或者通过其他保存的属性查看)。

The above principles should also apply to the UIImages themselves; 以上原则也应适用于UIImages本身; since you're saving them to disk, you don't necessarily need them all in memory, so think about releasing and getting them on demand. 由于要将它们保存到磁盘,因此不一定需要全部存储在内存中,因此请考虑按需发布它们。 One thing to note: Sometimes scrolling can get pretty slow when you're reading images from disk, so it's a tradeoff you'll need to investigate for yourself. 需要注意的一件事:有时候,当您从磁盘读取图像时,滚动会变得非常缓慢,因此这是一个折衷,您需要自己进行调查。

This has basically been solved for you by David Golighty . David Golighty基本上已经为您解决了这个问题 We've used the ImageCache code successfully for 600+ images without a hiccup. 我们已经成功使用ImageCache代码处理了600多个图像,而不会出现打h的情况。 Because of the way the caching works, we easily flip through 300 512x512 PNG images on both the iPhone and iPad with high frames-per-second. 由于缓存的工作方式,我们可以轻松地在iPhone和iPad上以每秒高帧数浏览300 512x512 PNG图像。

For one, resample them down to a reasonable size -- presumably, you only need them to be about the screen's size or smaller. 首先,将它们重新采样到合理的尺寸-大概您只需要它们等于屏幕的尺寸或更小即可。 If you zoom in, go get the original for just that image. 如果放大,则仅获取该图像的原始图像。

Also, make a custom view (subclass of UIView) that draws the image (in drawRect) when it's visible and unloads the image when it's off-screen. 另外,创建一个自定义视图(UIView的子类),以在可见时绘制图像(在drawRect中),并在屏幕外显示时卸载图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM