I found in the Bad Case, some CAAnimations even not start.
I hooked -[CALayer addAnimation:forKey:], -[UIViewAnimationState animationDidStart], and -[UIViewAnimationState animationDidStop:finished:] methods,
and log the info about the layers and animations.
By comparing the logs between the good case and bad case, I found that the animations are triggered by the Runloop's CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE function
In the bad case, the runloop is running in different mode(actually speaking, in different state, they all run in default mode)