I have an requirement where I had to load multiple images and videos in the ScrollView
but on iPad 2 my application crashes when I load entire set on one go.It says that application
exits due to heavy memory pressure.
I would like to know how to handle this issue and it it possible to load images one by one when i scroll? and if yes then how it can be done
I think The Best will be to use UITableView instead of scrollView. As tableview uses DEQUEUE so it will do the part of loading/unloading the visible portion of tableview. Table view cell can be customized any way You want.
Hope it will help.
Paging is the way to go.
If you load all the images in the memory then you are compromising scalability in big way for one or two image it will be fine for large number say hundreds it will crash.
One approach is you keep only three images in memory previous image----current image being displayed and ------next image ready for display. And you have to use lazy loading and image caching
Following links will help you
.Icarousel
.AFnetworking's uiimageview category for lazy loading and caching
.ASImageView a light weight uiimageview category if you dont want to integrate full AFNetworking in your project
Related
Oddly I can't find anything on this topic anywhere.
Basically, I have a simple UITableView with, lets say, 10 rows. Each row has a user associated with it, and each user has a "profile picture". Now lets say that each row was created by 1 of 2 users, so it will be displaying 1 of 2 different profile pictures in each of the rows.
I'm trying to be memory efficient, so I don't want to load the same image 5 times in a new UIImageView. So I tried using the exact same UIImageView reference in each of the rows for the same user, but it seems that only the last row to get loaded shows the ImageView. If, for example, a row that was offscreen becomes visible and reloads, the image will then appear for that row and disappear from the row where it was previously appearing.
So my question is, how can I do this?
A. A solution to what I'm trying to do/something I'm missing
B. IOS will not load the same image into memory AGAIN if I use it in a new UIImageView, so I'm just wasting my time worrying about this
C. A new solution that blows my mind
Thanks!
Steve
*Note, I'm building this in Xamarin/Mono but I don't think C# vs Objective C would make a difference in this case
UIImage has a built-in cache, so option B is most likely your solution. Because of this cache, there is probably no need to keep a single UIImage instance around to use in each UIImageView. While that approach may speed up your application slightly, it's more likely a case of premature optimization.
In addition, UITableView is highly optimized to reuse cells that move off screen so you will only ever have as many UIImageView instances as you have visible UITableViewCells.
Your problem was caused by the fact that UIViews can only have at most one superview at a time. So every time you added your single instance to a cell, it removed itself from the previous cell. That's why you only saw it on the very last cell.
I think you are misunderstanding how iOS draws images. You are going to need to create multiple UIImageViews in every spot the image is displayed, but you can (and should) reuse your UIImage object, and that's what really consumes memory.
So in your cellForRowAtIndexPath method, simply create an imageView and set it to the image which you've already loaded.
Reuse images, not imageViews.
I'm making a table view that downloads an image for the cell off the web, every time the cell is loaded.
This proves a problem though, as when you scroll down then up again, the cells are reloaded.
Is there any way to stop the unloading of cells, and control how many cells are loaded when the view appears?
I propose that instead of trying to stop your UITableView from reusing cells, which would decrease performance, you store the images you download, using NSCache for example.
NSCache works the same way as a Dictionary - with key value pairs. The main difference however is it incorporates various auto-removal policies, which ensure that it does not use too much of the system’s memory. Here's the documentation on NSCache: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSCache_Class/index.html
Using this method: when you're setting up your UITableViewCell, you could check if an image has been downloaded for that NSIndexPath. If an image hasn't been downloaded you download it and add it to the cache once its finished, otherwise you use your cache and get the image from there.
Which one is good to use for a page based design, Pageviewcontroller or UIScrollview with paging.
Which will consume less memory? I have done it via UIScrollview; but it's consuming very huge memory. Any help will be greatly appreciated.
Using UIScrollView for the application is not a handy task. For iOS 6, you should use UIPageViewController. But for iOS 5, UIPageViewController is not be good as it only provides scrolling for the page transition.
You may reuse the UIScrollView views then,
Many examples are there in SO like this
It is hard to say which is "best" - it depends on what makes sense for your app. Which ever approach you choose you can minimise memory consumption by "lazy loading" content into the scroll view when it is needed. For example, if you were displaying pages of images and the images are stored as files in your app then you should only add the current image and the image either side of the current image. As you scroll you can load and add the next image and release.
Here is a tutorial that shows this approach with UIScrollView- Multiple virtual pages in a UIScrollView with just 2 child views
UIPageViewController makes it a bit simpler by adopting a dataSource pattern, so you can concentrate on responding to data requests and not have to worry about manipulating the views.
people
My project has a social media stream which loads paged objects and also pulls to refresh. I am using an MGScrollView which extends UIScrollView and I am wondering how I can optimise it. The issue is that after hundreds of items are loaded into the stream, it will become quite a memory hog.
It's not really possible to use a page pattern as all my content varies in size. The items that appear can vary in complexity and number of sub views. Added to that, because of the pull to refresh feature, items can pop into the top of the stream making dropping and adding items on/off screen pretty tricky.
Does anyone know of any sweet project I can leverage to help me do this?
Files attached of stream screen dumped from the app itself:
I think you should try adding features (animation and pull to refresh) to UITableView instead of optimising the scrollview. TableView is the solution of memory issues on scroll view. But of course that will make you use more cpu.
I think, if you use table view, your cells' height will be dynamic. For performance concern, you can check this article about twitter's iOS application.
ehttp://engineering.twitter.com/2012/02/simple-strategies-for-smooth-animation.html
I have a uitableview that loads fairly large images in each cell and the cell heights vary depending on the size of the image. Scrolling performance is decent, but can sometimes be jerky.
I found these tips I found on the FieryRobot blog:
glassy-scrolling-with-uitableview
more-glassy-scrolling-with-uitableview
Does anyone have any tips for improving uitableview scrolling performance?
Cache the height of the rows (the table view can request this frequently)
Create a least-recently-used cache for the images used in the table (and invalidate all the inactive entries when you receive a memory warning)
Draw everything in the UITableViewCell's drawRect: if possible avoid subviews at all costs (or if you require the standard accessibility functionality, the content view's drawRect:)
Make your UITableViewCell's layer opaque (same goes for the content view if you have one)
Use the reusableCellIdentifier functionality as recommended by the UITableView examples/documentation
Avoid gradients/complicated graphical effects that aren't pre-baked into UIImages
If you are subclassing
UITableViewCell, don't use a Nib,
write it in code instead. It's much
faster than loading Nib files.
If you're using images, make sure
you're caching them so you don't
have to load from file more than
once for each (if you have the
memory -- you'd be surprised how
much space images take up).
Make as many elements opaque as
possible. Similarly, try not and use
images with transparency.
The developer behind Tweetie has written extensively about this and has some code that demonstrates how it was done for that app. Basically, he/she advocates one custom view per table cell, and drawing it manually (rather than subviewing with Interface Builder, among other options).
fast-scrolling-in-tweetie-with-uitableview
Also, Apple has updated its own sample code for TableView in its TableViewSuite tutorials (maybe in response to this?)
TableViewSuite
#1 performance killer for UITableView scrolling is drawing shadows on any cell view layer, so if scrolling performance matters then don't do shadows unless basically it doesn't slow down your main thread.
thought this had to be said since none of the accepted answers made mention of shadows and layers. :+)
Any problem with UITableView scrolling performance can be solved using techniques already described in other answers. However many a times sluggish performance is caused by something inherently erroneous, or repetitive.
The fact that UITableView reuses the cells, and the fact that each cell may need its own image - together makes the solution bit complex. From how it's being solved the general way, here I summarize things that should be taken care of:
Load data into data source - from REST / database. This step should be done on background, eventually using dispatch_async along with GCD queue.
Create and initialize relevant data model objects and putting them inside an array
[tableView reloaddata]
Inside cellForRowAtIndexPath, include code that will set data (text) from correct data model object of the array.
Now images maybe in the form of URL too, so this step might be little quirky because of cell reuse done by table view. The heart of the fact is to load once again image from device cache / URL using async queue, then set it to correct cell.image (whatever is your cell image property).
To avoid problems, refer to this tutorial about lazy loading of images inside table view.