Hi Tom,

Definitely write a Radar.

One thing you could try is overriding both -checkTextInRange:types:options: & 
-handleTextCheckingResults:forRange:types:options:orthography:wordCount: for 
your field editor.

You can have some kind of the field editor session ID.

Every time a new field editor starts, you increment the ID.  Then, inside your 
-checkTextInRange:, you can pass the session ID via the options dict to super.

Inside -handleTextCheckingResult:, validate the session ID inside the options 
dict against the current ID.  Forward the message to super only when they match.

Aki

On 2011/08/02, at 17:36, Thomas Bunch wrote:

> Hello, fellow cocoa devs.
> 
> I'm running down the most common crasher we're seeing in OmniPlan-2.0 under 
> Lion and running onto some grief with NSSpellChecker/NSTextView.  We have a 
> fairly complex outline view that is backed by many text storages and the 
> field editor is asked to do a lot. When editing a row, we create a text 
> storage for that row's contents, then insert a field editor into the view 
> hierarchy and call -replaceTextStorage: on its layout manager with our 
> freshly-minted text storage.
> 
> If I enable “Correct Spelling Automatically”, create a new task and title it 
> "Hello htere" [sic], spell checking is performed asynchronously on the main 
> thread and the NSSpellChecker shows a correctionIndicator
> 
> #0  0x00007fff8c295a5b in -[NSSpellChecker 
> showCorrectionIndicatorOfType:primaryString:alternativeStrings:forStringInRect:view:completionHandler:]
>  ()
> #1  0x00007fff8bf12cef in -[NSTextView 
> handleTextCheckingResults:forRange:types:options:orthography:wordCount:] ()
> #2  0x00007fff8bf11565 in -[NSTextView 
> _handleTextCheckingResults:sequenceNumber:forRange:types:options:orthography:wordCount:applyNow:]
>  ()
> #3  0x00007fff8bf113e6 in __-[NSTextView 
> checkTextInRange:types:options:]_block_invoke_2 ()
> #4  0x00007fff896a6ecc in __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ ()
> #5  0x00007fff8965efa2 in __CFRunLoopDoBlocks ()
> #6  0x00007fff89686f07 in __CFRunLoopRun ()
> …
> 
> If I hit return, the default correction is selected and I infer that the 
> completionHandler is enqueued on the main queue. However, our custom 
> implementation of -insertNewline: will also end editing on the current row, 
> create a new item with another text storage behind it, and tell the field 
> editor's layout manager to replaceTextStorage: with that new row's text 
> storage. After we return to the run loop, an NSPortMessage happens to be 
> received by another object, and that object calls [NSApp 
> nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] 
> inMode:NSEventTrackingRunLoopMode dequeue:NO], which will again fire the run 
> loop. This causes the the main queue to fire its pending blocks, and thus the 
> NSTextView's text checking handler's completionHandler is run and raises an 
> exception: 
> 
> #13 0x00007fff896f1ab4 in +[NSException raise:format:] ()
> #14 0x00007fff896af87e in -[__NSCFString characterAtIndex:] ()
> #15 0x00007fff8bf17e76 in 
> -[NSAttributedString(NSAttributedStringKitAdditions) 
> doubleClickAtIndex:inRange:] ()
> #16 0x00007fff8bf17de7 in 
> -[NSAttributedString(NSAttributedStringKitAdditions) doubleClickAtIndex:] ()
> #17 0x00007fff8bf17da4 in -[NSTextView _doubleClickAtIndex:limitedRangeOK:] ()
> #18 0x00007fff8c304d61 in __-[NSTextView 
> handleTextCheckingResults:forRange:types:options:orthography:wordCount:]_block_invoke_2
>  ()
> #19 0x00007fff8dbdf90a in _dispatch_call_block_and_release ()
> #20 0x00007fff8dbe177a in _dispatch_main_queue_callback_4CF ()
> #21 0x00007fff89686ddc in __CFRunLoopRun ()
> #22 0x00007fff896863e6 in CFRunLoopRunSpecific ()
> #23 0x00007fff90e5c697 in RunCurrentEventLoopInMode ()
> #24 0x00007fff90e63db9 in ReceiveNextEventCommon ()
> #25 0x00007fff90e63c46 in BlockUntilNextEventMatchingListInMode ()
> #26 0x00007fff8bd2baf5 in _DPSNextEvent ()
> #27 0x00007fff8bd2b3fc in -[NSApplication 
> nextEventMatchingMask:untilDate:inMode:dequeue:] ()
> …
> 
> Here, this problem occurs because the field editor's new NSTextStorage is 
> shorter now (having a default task title of something like “Task 2”). The 
> completion handler appears to be hanging on to the range of the 
> NSTextCheckingResult it's handling, (NSRange){6, 5}. The exception we get is:
> 
> ---------------------------
> Mask: 0x00000001
> Name: NSRangeException
> Reason: -[__NSCFString characterAtIndex:]: Range or index out of bounds
> Info:
> 
> Because we regard an unhandled exception in a place like this as a potential 
> data corruptor, we immediately crash on purpose and hope the user will send 
> in a crash report with a backtrace to the scene of the crime.
> 
> It just looks to me like it's unsafe to change the text storage backing the 
> field editor unless you can be sure that there are no text checking 
> completion blocks hanging around on the main dispatch queue. I don't believe 
> there's any API or trick to get the spell checker to wrap up its text 
> checking now, synchronously. Subclassing [NSTextView 
> handleTextCheckingResults:forRange:types:options:orthography:wordCount:] in 
> our field editor would be pretty onerous; it's a very complicated method.
> 
> Your thoughts would be very welcome.  I'm happy to provide more information 
> of course, but I've got over half a million lines of .m files here and I'm 
> trying to narrow the scope of the problem suitably. Kyle is currently across 
> the hall striving to reproduce this problem in a smaller, Radar-compatible 
> sample project.
> 
> Thanks!
> 
> -Tom_______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/aki%40apple.com
> 
> This email sent to a...@apple.com

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to