iOS AVPlayer replaceCurrentItemWithPlayerItem:nil block UI Thread - ios

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

Related

Find cause of: "This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread."

I have a large application that uses a number of third-party libraries and am now seeing the following error in the logs: "This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes."
From what I have found here on SO, this is probably being caused by a UI element being changed on a background thread, which is triggering the autolayout. Unfortunately, we have so many UI elements being changed by so many different moving parts that I do not know the best way to find the culprit.
Can anyone tell me how can I found out what exactly is triggering the autolayout change from a background thread?
Sometimes it's not a completion block, but anything that is performed in the background.
In my case it was notifications that where sent. I implemented iCloud in my app, which means that when data was edited or added on another device, the other app(s) receive an iCloud update/notification, which triggered an update of the UITableView.
The code to update the UITableView was not done in the MainThread. Adding the code as shown in the comments fixes it.

Problems with a UITableView in swift

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.

UISlider / touch events changes in iOS 7

I've encountered a problem with iOS 7 which I believe is related to the way events are handled.
I have a slider which upon changing it's value does some image processing which takes about 100ms to complete. In iOS 6, I could see the image change as the slider is dragged. After upgrading to iOS 7 it seems that the view is not redrawn between invocations of the value changed events. While dragging the slider, I can see the image processing start and finish numerous times but the entire view doesn't refresh (including the slider's thumb) until I stop sliding. Also the same happen when I add a gesture handler to the view which does the same thing. Has anyone encountered a similar problem?
Thanks.
Make sure you are not doing that processing on the main thread. I recommend using GCD to dispatch the processing onto a separate queue - it takes very little code and uses a well established pattern that is easy to understand.

UIViewController animations stop working

My app runs fine in iOS6, but in an unspecified upcoming version of iOS that I cannot name for NDA reasons, all UIViewController transition animations stop working. New views just pop into place instantly. I am not sure if this unspecified future version of iOS is the cause, as I've seen this happen occasionally in iOS6.
Sometimes animations start working for a while and then stop shortly after, making me think it's some sort of memory warning issue, but my app is using a fairly reasonable ~125MB of RAM at most times. Can anyone offer any advice or things to investigate?
The described behavior has always existed: if you do work on background threads and then call and UIKit methods then more often than not the update will be delayed in a weird way.
Because of this you should always dispatch_async onto the main queue to update the UI.
Those bugs are very hard to catch since they do not always occur predictably.
To catch them I built a method that swizzles some UIKit methods to check if they are called on the main thread. This allows you to stop on a symbolic breakpoint, whenever you have forgotten to dispatch back onto main queue.
https://github.com/Cocoanetics/DTFoundation/blob/develop/Core/Source/iOS/Debug/UIView%2BDTDebug.m
A good workaround from the Apple dev forums on this issue:
Do this:
[UIView setAnimationsEnabled:YES]
And animations start working again. I suspect that this is either a straight up iOS7 bug, or somewhere in my code an animation or UIViewController launch is happening on a background thread, causing animations to stop. Probably unrelated to the unspecified future version of iOS.
This issue appears to be caused by doing UIKit stuff in background threads. I have a pre-render cache full of NSOperations that renders complex UIViews to UIImages to cache the output. This seemed to work fine in iOS6, but probably does cross the line somewhat. I'll need to replace this functionality with something that renders images and text to a graphics buffer rather than using UIViews and UILabels at all.
All you have to do is catch hold of main queue while updating UI on receiving response from an API.Ios uses main queue by default for updating UI but it is not 100 percent efficient.Hence you have to make sure that the UI gets updated on main thread only and the way to do that is as below:
DispatchQueue.main.async{
//UI related code eg:
self.label.text = "abc"
self.button.setTitle("xyz",.normal)
self.tableView.reloadData()
}
If you are not catching hold of main thread animations may or may not work.
But if you are using main thread animations will definetely work.
Correct Code while updating UI on api response:
Alamofire.getApiCall(paramaters: parameters, completion:{
response in
// UI related code.
DispatchQueue.main.async{
self.label.text = "abc"
self.button.setTitle("xyz",.normal)
self.tableView.reloadData()
}
})
Incorrect Code which may cause animations to stop and lead to weird crashes:
Alamofire.getApiCall(paramaters: parameters, completion:{
response in
// UI related code.
self.label.text = "abc"
self.button.setTitle("xyz",.normal)
self.tableView.reloadData()
})

iOS capture view with background 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.

Resources