Search code examples
iosswiftprogram-entry-pointuiviewanimationdispatch-queue

Serial Queue sync method interrupting UIView animation on Main


I am having an issue where I have a progress bar animation running on main being interrupted by sync calls to my Serial Queue.

Previously I did not use this queue as a serial queue, and only as an asynchronous queue -- however this lead to issues when handling entering background/foreground transitions and I had to treat the queue as synchronous and call only sync instead of async on it.

Now, flow wise the queue keeps my application working flawlessly -- except for the UIView animation now stutters (sometimes for over a second) depending on the load of each sync call to my serial queue.

Is there anyway to allow sync calls to my serial queue without causing these stutters in my UIView animation? I've tried dynamically calling a new animation in each sync block to my serial queue, but that doesn't fix the issue.


Solution

  • Please try below things:

    1. Create NSOperationQueue. Set max concurrent task 1. It will execute serial queue pattern
    2. Create NSOperation Subclass (Suppose CustomOperation) and write your desired code in main method. Once desired job completed trigger finish and switch to main Thread and do Progress bar update things or other
    3. Create Object(s) of CustomOperation and all of them to step 1 queue

    class CustomOperation: Operation {

    var identifier:String?
    var index:Int?
    
    override func main() {
        /// do sync or async tasks
    
        //// post completion tasks
    
        NotificationCenter.default.post(name: NSNotification.Name("TASKDONE"), object: self)
    }
    

    }

    func addOperations() {

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.trackOperation(operation:)), name: NSNotification.Name(rawValue: "TASKDONE"), object: nil)
    
    let operationQueue = OperationQueue()
    var items = [CustomOperation]()
    for index in 0..<10 {
        let operation = CustomOperation()
        operation.index = index
        operation.name = "Operation:\(index)"
        items.append(operation)
    }
    operationQueue.maxConcurrentOperationCount = 1
    operationQueue.addOperations(items, waitUntilFinished: false)
    

    }