Speeding Up TextArea Modifications In OS X

When doing a lot of manipulation to a TextArea’s contents under Cocoa, performance can suffer due to the underlying NSTextView doing work on layout and glyph selection. This can be sped up by telling the text view that you’re going to begin editing. You can do this by using a few Cocoa Declares.

The Declare statements are relatively simple:

Declare Function documentView Lib "AppKit" Selector "documentView" _ ( obj As Integer ) As Integer Declare Function textStorage Lib "AppKit" Selector "textStorage" _ ( obj As Integer ) As Integer Declare Sub beginEditing Lib "AppKit" Selector "beginEditing" _ ( obj As Integer ) Declare Sub endEditing Lib "AppKit" Selector "endEditing" _ ( obj As Integer )

These Declares give you access to methods for enabling “batch-editing mode” for the underlying NSTextView.

First, you want to get the text storage for the document, which is a two-step process. In the first step, you take the TextArea’s Handle property (an NSScrollView instance) and ask for its document view:

Dim docView As Integer docView = documentView(MyTextArea.Handle)

Now you get the NSTextStorage for the NSTextView:

Dim storage As Integer storage = textStorage(docView)

With the text storage, you can now enable batch-editing mode by calling beginEditing:

beginEditing(storage)

Now you can make your significant changes to the TextArea:

For i As Integer = 0 To 5000 MyTextArea.AppendText("Lorem ipsum dolor sit amet. ") Next

And when you are finished disable batch-editing mode:

endEditing(storage)

So how much does this improve performance? In my tests, the For loop by itself takes about 4.3 seconds to complete. Using batch-edit mode with these Declares drops it to 0.02 seconds. That’s almost instantaneous!

If you find you are going to use these Declare often, you can add them to a module as Extension methods so that you can call them more easily (as shown in the sample project):

Originally published on November 26, 2012 by Joe Ranieri

