Using a custom NSLayoutManager no longer works in Sierra

Originator:bya
Number:rdar://27976865 Date Originated:8/23/2016
Status:Open Resolved:No
Product:OS X SDK Product Version:10.12 Beta (16A304a)
Classification:Serious Bug Reproducible:Yes
 
Our app uses a custom NSLayoutManager and a NSTextStorage. In a recent Sierra beta, this stopped working. As a result, our app has become unusable: it's text editor is blank and doesn't accept input.

I've isolated the problem to using our custom layout manager, and have attached a zip file that contains 1) the source code for a very simple application that exhibits the error and 2) this application compiled on El Capitan.

The included application, LayoutManagerBug_ElCap, works fine on El Capitan but won't show text or accept input on Sierra. So, this isn't just an issue with compiling on Sierra - it affects applications compiled on El Cap as well.

This is quite urgent for us, and we hope you have a fix, or a suggested workaround, for us soon.

Steps to Reproduce:
1. Run the included application, LayoutManagerBug_ElCap, on the most recent Sierra beta.
2. Notice how it does not display the appropriate text ("This is a test.") and doesn't allow any input.

In the included source:
1. Compile and run the attached project on Sierra.
2. Notice how the app does not display the appropriate text ("This is a test.") and doesn't allow any input.
3. In the following code, change the "#if 1" (which creates a "custom" layout manager) to an "#if 0":

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
#if 1
    // Create our own layout manager
    NSLayoutManager *lm = [[NSLayoutManager alloc] init];
    [lm addTextContainer:self.textView.textContainer];
#else
    // If we don't create our own layout manager, everything
    // works fine. To test, change the "#if 1" above to an "#if 0".
    NSLayoutManager *lm = self.textView.layoutManager;
#endif
    
    // Create our own text storage
    _textStorage = [[NSTextStorage alloc] init];
    [lm replaceTextStorage:self.textStorage];
    
    // Add "This is a test." to our own text storage.
    // We expect to see this in our text view.
    NSAttributedString *aString =[[NSAttributedString alloc] initWithString:@"This is a test."];
    [self.textStorage appendAttributedString:aString];
}

4. Run again.
5. Revel in a working application.

Expected Results:
The application that is compiled on El Cap and works on El Cap should also work in Sierra.

Actual Results:
The application does not display the appropriate text ("This is a test.") and doesn't allow any input.

Version:
OS: 10.12 Beta (16A304a)
Xcode: Version 8.0 beta 6 (8S201h)

Notes:
Perhaps this is why Xcode 7 crashes in Sierra?
http://stackoverflow.com/questions/38903699/xcode-7-3-1-crashes-on-macos-sierra-beta-5

Configuration:
This occurs on computers running recent Sierra betas

Comments

Here's a workaround

Here's the code that works on El Cap, but not on Sierra:

[lm addTextContainer:self.textView.textContainer];

Instead, if I do:

[self.textView.textContainer replaceLayoutManager:lm];

then everything seems to work.


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!