Two problems trying to use NSTextView for a scrolling console/terminal like view
Two problems trying to use NSTextView for a scrolling console/terminal like view
- Subject: Two problems trying to use NSTextView for a scrolling console/terminal like view
- From: Eric Wing <email@hidden>
- Date: Sat, 28 Dec 2013 15:14:10 -0800
I’ve been prototyping an internal tool that receives and displays lots
of text data. I wanted to display this kind of like how Terminal.app
continuously appends text and keeps scrolling to the bottom as more
data is added.
I used a stock NSTextView and keep appending to the backing NSTextStorage.
I found a solution to autoscrolling on stackoverflow which I incorporated.
http://stackoverflow.com/questions/15546808/scrolling-nstextview-to-bottom
- (void) postLogEvent:(NSString*)log_message
{
BOOL scroll = (NSMaxY([[self logStreamTextView] visibleRect]) ==
NSMaxY([[self logStreamTextView] bounds]));
[[[[self logStreamTextView] textStorage] mutableString]
appendString:log_message];
if (scroll) // Scroll to end of the textview contents
{
[[self logStreamTextView] scrollRangeToVisible: NSMakeRange([[[self
logStreamTextView] string] length], 0)];
}
}
This works, but I encountered two problems when the data set gets large.
1) Somewhere after 40,000 lines of text, the application starts
becoming unresponsive. Around 50k-60k, the application feels hung and
I have to force kill it. I figured out that the bottleneck was in
scrollRangeToVisible call.
I’ve posted 3 screenshots from Instruments here:
https://picasaweb.google.com/ewmailing/AutoscrollingNSTextViewTrace#5962576581630914370
2) If I disable autoscrolling, performance is fine. I got to around
150,000 lines without any problems. But at some point later (my test
runs for several hours so I usually leave it unattended and it can
generate a million lines, so I don’t know exactly when), Cocoa raised
an exception at:
-[NSBigMutableString replaceCharactersInRange:withString:]: nil argument
(Full exception trace is below for interest.)
So I was wondering if there were any better techniques to avoid my two
problems or how I should go about resolving them. Since this is an
internal tool to help something else, I'm looking for simple/quick
solutions, though for my own curiosity, I also do wonder what the
proper solution is.
Thanks,
Eric
An uncaught exception was raised
2013-12-28 07:41:50.304 Test262LogClient[44722:303] ***
-[NSBigMutableString replaceCharactersInRange:withString:]: nil
argument
2013-12-28 07:41:50.305 Test262LogClient[44722:303] (
0 CoreFoundation 0x00007fff92d6e41c
__exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8b7ebe75
objc_exception_throw + 43
2 CoreFoundation 0x00007fff92d6e2cc
+[NSException raise:format:] + 204
3 Foundation 0x00007fff928430e4
-[NSBigMutableString replaceCharactersInRange:withString:] + 111
4 Foundation 0x00007fff9284185e
-[NSConcreteMutableAttributedString
replaceCharactersInRange:withString:] + 295
5 AppKit 0x00007fff893ff136
-[NSConcreteTextStorage replaceCharactersInRange:withString:] + 77
6 Test262LogClient 0x00000001000020bf
-[LogStreamWindowController postLogEvent:] + 591
7 Test262LogClient 0x0000000100010533
__69-[ResolveForLogStreamDelegate
connectToServerAndSendStreamDirective:]_block_invoke_256 + 67
8 libdispatch.dylib 0x00007fff8c3e11d7
_dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x00007fff8c3de2ad
_dispatch_client_callout + 8
10 libdispatch.dylib 0x00007fff8c3e5f03
_dispatch_main_queue_callback_4CF + 333
11 CoreFoundation 0x00007fff92cd5839
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
12 CoreFoundation 0x00007fff92c90b14
__CFRunLoopRun + 1636
13 CoreFoundation 0x00007fff92c90275
CFRunLoopRunSpecific + 309
14 HIToolbox 0x00007fff8b9baf0d
RunCurrentEventLoopInMode + 226
15 HIToolbox 0x00007fff8b9bacb7
ReceiveNextEventCommon + 479
16 HIToolbox 0x00007fff8b9baabc
_BlockUntilNextEventMatchingListInModeWithFilter + 65
17 AppKit 0x00007fff891a228e _DPSNextEvent + 1434
18 AppKit 0x00007fff891a18db
-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
19 AppKit 0x00007fff891959cc
-[NSApplication run] + 553
20 AppKit 0x00007fff89180803
NSApplicationMain + 940
21 Test262LogClient 0x000000010005f962 main + 34
22 libdyld.dylib 0x00007fff8d6245fd start + 1
23 ??? 0x0000000000000003 0x0 + 3
)
2013-12-28 07:41:50.307 Test262LogClient[44722:303] *** Terminating
app due to uncaught exception 'NSInvalidArgumentException', reason:
'*** -[NSBigMutableString replaceCharactersInRange:withString:]: nil
argument'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff92d6e41c
__exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8b7ebe75
objc_exception_throw + 43
2 CoreFoundation 0x00007fff92d6e2cc
+[NSException raise:format:] + 204
3 Foundation 0x00007fff928430e4
-[NSBigMutableString replaceCharactersInRange:withString:] + 111
4 Foundation 0x00007fff9284185e
-[NSConcreteMutableAttributedString
replaceCharactersInRange:withString:] + 295
5 AppKit 0x00007fff893ff136
-[NSConcreteTextStorage replaceCharactersInRange:withString:] + 77
6 Test262LogClient 0x00000001000020bf
-[LogStreamWindowController postLogEvent:] + 591
7 Test262LogClient 0x0000000100010533
__69-[ResolveForLogStreamDelegate
connectToServerAndSendStreamDirective:]_block_invoke_256 + 67
8 libdispatch.dylib 0x00007fff8c3e11d7
_dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x00007fff8c3de2ad
_dispatch_client_callout + 8
10 libdispatch.dylib 0x00007fff8c3e5f03
_dispatch_main_queue_callback_4CF + 333
11 CoreFoundation 0x00007fff92cd5839
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
12 CoreFoundation 0x00007fff92c90b14
__CFRunLoopRun + 1636
13 CoreFoundation 0x00007fff92c90275
CFRunLoopRunSpecific + 309
14 HIToolbox 0x00007fff8b9baf0d
RunCurrentEventLoopInMode + 226
15 HIToolbox 0x00007fff8b9bacb7
ReceiveNextEventCommon + 479
16 HIToolbox 0x00007fff8b9baabc
_BlockUntilNextEventMatchingListInModeWithFilter + 65
17 AppKit 0x00007fff891a228e _DPSNextEvent + 1434
18 AppKit 0x00007fff891a18db
-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
19 AppKit 0x00007fff891959cc
-[NSApplication run] + 553
20 AppKit 0x00007fff89180803
NSApplicationMain + 940
21 Test262LogClient 0x000000010005f962 main + 34
22 libdyld.dylib 0x00007fff8d6245fd start + 1
23 ??? 0x0000000000000003 0x0 + 3
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden