Lesson for today
So today we had an interesting issue at Kobo: [[NSThread currentThread] threadDictionary]
was returning nil
. This is never supposed to happen, as it’s created on demand.
After some investigation, we noticed that stack leading to the -layoutSubviews
call which resulted in this failure started at +[NSThread exit]
, going through pthread_exit()
and pthread_tsd_cleanup()
. This latter function apparently cleaned up a CoreAnimation flag or some such which indicated that a view needed to laid out again, thus causing -layoutSubviews
to be called on a background thread, and moreover on a background thread which had already had its Foundation-level context deleted.
This raises the question: why the hell does the documentation for -[UIView setNeedsLayout]
not mention that it’s using per-thread flags, thus causing rendering to occur on the same thread which calls this method? Since it sets a flag for CoreAnimation to act upon later, I’d always assumed that said flag would be inspected by the display link on the main thread, not on the current thread.
So, that leads to today’s hard-learned lesson:
Do not call -[UIView setNeedsLayout]
on a background thread. Ever.