For better performance on scrolling the UItableView. I was adviced to draw the cells in a background thread.
But some one said that, update UI in background thread is not recommended, this can crash the app.
Is it possible to draw cells in background thread?
You very well can draw on a background thread - and then capture that drawing as an image and send that back to the main thread; there an image view displays the image you draw in the background.
If you have access to the Apple developer site, watch the WWDC 2012 Video "Building Concurrent User Interfaces on iOS". You don't want to actually lay out UIView instances and so forth but just use the various Core Graphics drawing functions.
You can not do that , every view would draw itself at the time when it comes to foreground, it would do nothing in background.
Drawing UI in background not only can crash but in most cases will crash the app.
Make sure you're using dequeueReusableCellWithIdentifier: message for getting cells.
Revise your tableView:cellForRowAtIndexPath: delegate to find what consumes most resources. It could be, e.q. hard UIImage processing or something similar. You should consider move all the processing, generating data and such things out of your cell creating. Only set appropriate data in cell and return it. I'm pretty sure it'll reduce your performance issues greatly.
Related
I'm working to improve the performance of images displayed to the user. I have removed alpha blending and am assigning a scaled/correctly sized image to the UIImageView already along with some caching. However, also as a part of this I am thinking of moving setHiglightedImage: call to background thread.
ImageView is wrapped in UIKit which says that any modification to layouts should be done on main thread. However while assigning an image with a highlightedImage we're not triggering any layout changes or invoking any constraints. Would this be a valid change that doesn't violate UIKit rules? Are there going to be any exceptions thrown because of this?
I don't see any problems or warnings by debugger while running this so far on background thread. Also the apple's official documentation (here and here) around UIImageView doesn't specify anything about this being on background thread. I tried searching more online about doing this, but couldn't really find anything helpful
Is there any reason for [UIImageView setHighlightedImage:] to not be on background thread? Will it have any performance benefits?
setHighlightedImage is changing the user interface . You can not run it on a background thread.
In a Cocoa application, the main thread runs the user interface, that
is, all drawing and all events are handled on the main thread. If your
application performs any lengthy synchronous operations on that
thread, your user interface can become unresponsive and trigger the
spinning cursor. To avoid this, you should shorten the amount of time
consumed by those operations, defer their execution, or move them to
secondary threads.
Apple Documentation
It seems that the api replaceCurrentItemWithPlayerItem: will stuck the main thread for some seconds, I understand that replacing the item need the information of the new item which might take some time to preload. But questions come up that why replaceCurrentItemWithPlayerItem: with a nil item object would also stuck the main thread?? It happens to me that sometimes it take more than 5 seconds to replace a nil playerItem.
I wonder what can I do to avoid the issue. Thanks for any advices!
I came across a similar blocking UI thread issue when I used UICollectionView to display and preview video in local photo library via ALAssetLibrary.
The scroll on switching videos is not smoothly,so I guess some method block UI thread.Then I use Core Animation of Instruments to analyze what exactly occupy the UI thread.In Time Profiler I found out that replaceCurrentItemWithPlayerItem need about 30ms to execute in main thread,which is more than 16ms (1000/60(fps)) result in choppy scrolling.
To solve the problem,first I tried that put replaceCurrentItemWithPlayerItem in to background thread using GCD,but It not work.I'm not sure if it is because the Cocoa itself need update UI when call replaceCurrentItemWithPlayerItem,which means the UI thread is still block.Finally I made it work by putting replaceCurrentItemWithPlayerItem at the scrolling end (the delegate func scrollViewDidEndDecelerating(scrollView: UIScrollView)).Now the scrolling is smoothly,yep!
Therefore,my advice is obvious : Using Instruments to analyse what exactly occupy the UI thread
I've got an app which stores images taken by the camera in a table view. I have a problem where the images (using apple's queuing system for memory management) are not able to load as fast as the user can scroll (it stops then jumps when the image loads) and sometimes the app crashes. This is on an iPod 5. I understand that this is because of the fact it cannot load the images quickly enough. Does anybody have any suggestions for how to do this? I know it can be done because of the existence of the music app and such.
Thanks.
Check out this great tutorial.
http://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift
It uses NSOperation to achieve your goal.
Load images in background thread. You can use Dispatch_async or NSOperationQueue to get images in background. Your main thread will continue executing UI events.
How would I constantly refresh a background image of my UIImageView, while also still listening for touches and input? What I am looking for is the iOS Objective C equivalent (in java) of creating a new thread apart from the main thread, and having that thread be devoted to updating the background picture as fast as possible. Thanks!
It depends on where the new images are coming from. If they are a cycle of known existing images in your app bundle, just make this an animated image view (or an animated image) and the cycle will happen automatically.
If you need to run code e.g. to get out to the network periodically, then just start a repeating NSTimer. It calls you on the main thread, but your main thread code will be very brief indeed, and networking takes place asynchronously (unless you mess that up deliberately). Just make sure that when you actually set the image, you step out to the main thread, as you must never touch the interface in any way except on the main thread.
I'm not sure how to efficiently capture the screen on a pixel-dense iOS device such as the iPad 3 (2048x1536). I've seen some examples such as this & this:
However, these solutions are too slow. I would like the view to be periodically captured maybe a few times a second, but the capturing mechanism is slow enough that if I executed this in the main thread, the UI would lock up. I was wondering whether it's possible to somehow delegate this to a background thread? Or perhaps there's a more efficient view capturing function? Thanks in advance.