DispatchQueue.main.asyncAfter method freeze UI in a particular call

1.8k views Asked by At

I'm calling the DispatchQueue.main.asyncAfter method after I modify a property of an object (I'm firing it with KVO). I'm only showing a confirm view for a second and then run a block which do another things on the UI (pops a viewcontroller). The problem is that when i call this from a UICollectionViewCell works fine, but when i call this method from another particular UICollectionViewCell in my app, it freezes up. The method is implemented in a extension of UIView.

public func showConfirmViewWith(title: String!, frame: CGRect? = screenBounds, afterAction: (() -> Void)?) {

    let confirm = ConfirmationView(frame: frame!, title: title)

    self.addSubview(confirm)

    confirm.checkBox?.setCheckState(.checked, animated: true)

    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) ) {

        if afterAction != nil  {
            afterAction!()
        }
       confirm.removeFromSuperview()
    }
}

When it freezes the code inside the Dispatch never gets called, I have a breakpoint inside, but never gets to that point.

UDPATE Here's the stack trace when i pause the execution:

First time I paused the execution

1

There are 1 answers

0
sheinix On BEST ANSWER

I solved this tricky bug. First thing, there wasn't any problem with the DispatchQueue.main.asyncAfter call. The app was going into a loop and wasn't any signs that was lock. I ran the profiler and saw that the layout of some constraints was being called over and over. I have a tableView inside the collectionViewCell, and an animation when finish the call to asyncAfter. The problem was that the overriden method layoutSubviews has a tableView.reloadData() inside, so everytime i was trying to exit after the async call with an animation, the layoutsubviews was being called and the reloadData() triggered over and over again. I'm not sure why that reloadData was there, but seems to be working fine now.