NSLayoutManager background layout races its delegate

Originator:rix.rob
Number:rdar://18505884 Date Originated:30-Sep-2014 05:07 PM
Status:Open Resolved:
Product:OS X Product Version:Mac OS X 10.9.5 (13F34)
Classification:Serious Bug Reproducible:Sometimes
 
Summary:
NSLayoutManagers with their delegates set to some NSLayoutManagerDelegate-conformant object are prone to a race condition between background layout and the delegate being deallocated.

1. The layout manager posts its background layout notification.
2. The delegate object deallocates, nil’ing out the layout manager’s delegate.
3. The layout manager’s background layout is performed.

At this point the layout manager still holds an unowned reference to the delegate instance. I’m not clear on how; the object in question was the text view’s superview in this case, but the reference to the superview is nil by the time the background layout is performed, so it’s unclear whether it’s copying an unowned reference to the delegate for the sake of the background layout or if something weirder is going on.


Steps to Reproduce:
1. Instantiate an object owning a text view.
2. Set the textView.textContainer.layoutManager.delegate to this object.
3. Make sure it’ll display and kick off background layout.
4. Release the reference to the root object, causing it all to be freed.
5. In the object’s dealloc, nil out the layout manager’s delegate.
6. Ensure background layout is enabled.
7. Do 1 through 3 repeatedly on the main thread’s run loop, e.g. in a recursive dispatch_async to the main queue.

Expected Results:
I expected everything to be fine.

Actual Results:
Crashes.

Regression:
Doesn’t happen without background layout. Doesn’t happen if you don’t set the layout manager’s delegate AFAICS. Probably doesn’t happen if the layout manager’s delegate is simply never deallocated.

Notes:
Backtrace to follow.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!