问题
I am getting this crash after converting an existing UIViewController
to Auto Layout and I can't figure out what is causing it. I did search for dispatch_async(dispatch_get_global_queue(...))
calls but none changes layout.
The stack trace is also very unhelpful:
* thread #18: tid = 0x73617, 0x0000000183aa8524 libobjc.A.dylib`objc_exception_throw, stop reason = breakpoint 3.1
* frame #0: 0x0000000183aa8524 libobjc.A.dylib`objc_exception_throw
frame #1: 0x0000000185071100 CoreFoundation`+[NSException raise:format:] + 116
frame #2: 0x0000000185c83894 Foundation`_AssertAutolayoutOnAllowedThreadsOnly + 192
frame #3: 0x0000000185c835d4 Foundation`-[NSISEngine _optimizeWithoutRebuilding] + 76
frame #4: 0x0000000185aceddc Foundation`-[NSISEngine optimize] + 112
frame #5: 0x0000000185c82270 Foundation`-[NSISEngine performPendingChangeNotifications] + 112
frame #6: 0x000000018af23e18 UIKit`-[UIView(Hierarchy) layoutSubviews] + 220
frame #7: 0x000000018b15fff8 UIKit`-[UISlider layoutSubviews] + 192
frame #8: 0x000000018af23a80 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1196
frame #9: 0x00000001883d19d8 QuartzCore`-[CALayer layoutSublayers] + 148
frame #10: 0x00000001883c64cc QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 292
frame #11: 0x00000001883c638c QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
frame #12: 0x00000001883433e0 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 252
frame #13: 0x000000018836aa68 QuartzCore`CA::Transaction::commit() + 512
frame #14: 0x000000018836af34 QuartzCore`CA::Transaction::release_thread(void*) + 660
frame #15: 0x0000000184103fbc libsystem_pthread.dylib`_pthread_tsd_cleanup + 572
frame #16: 0x0000000184103ce4 libsystem_pthread.dylib`_pthread_exit + 200
frame #17: 0x0000000184103378 libsystem_pthread.dylib`_pthread_wqthread + 1504
frame #18: 0x0000000184102d8c libsystem_pthread.dylib`start_wqthread + 4
(lldb)
Is there any way to figure out the exact place that triggered the layout?
回答1:
I finally found out the problem after taking another look at the stack trace. The problem was that I was changing the value
property of a UISlider
instance on a background thread.
But nowhere does it state that you have to change it on the main thread! (Thanks, Apple) Apparently, it seems like UISlider
implements the value
's setter and forces a layout or something similar.
来源:https://stackoverflow.com/questions/43071654/modifications-to-the-layout-engine-must-not-be-performed-from-a-background-threa