2012-05-25 172 views
10

我的一些用户正在得到这个崩溃。drawRect中的崩溃 - 导致它的原因是什么?

据我所知,它以某种方式连接到我的子类NSTextView-drawRect:方法,但我无法看到可能导致它的原因,并且压力测试未能摆脱该错误。

代码的drawRect

- (NSRange)visibleRangeOfTextView:(NSRect) rect { 
    NSLayoutManager *layoutManager = [self 
             layoutManager]; 
    NSTextContainer *textContainer = [self 
             textContainer]; 
    NSRange glyphRange, characterRange; 
    // first transform to text container coordinates 
    NSPoint containerOrigin = [self textContainerOrigin]; 
    rect.origin.x -= containerOrigin.x; 
    rect.origin.y -= containerOrigin.y; 

    // next, compute glyph range 
    glyphRange = [layoutManager glyphRangeForBoundingRect:rect inTextContainer:textContainer]; 

    // finally, compute character range 
    characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL]; 
    return characterRange; 
} 

- (NSRect)rectForCharacterRange:(NSRange)charRange 
{ 
    NSRect rect = [self 
        firstRectForCharacterRange:charRange]; 
    rect.origin = [[self window] 
        convertScreenToBase:rect.origin]; 
    rect = [self convertRect:rect fromView:nil]; 
    if (!rect.size.width) rect.size.width = 6.0; 
    return rect; 
} 

- (void)drawRect:(NSRect)dirtyRect 
{ 
    [super drawRect:dirtyRect]; 
    NSLog(@"Marking it"); 
    NSMutableArray *arr = [[NSMutableArray alloc] init]; 
    NSRange visible = [self visibleRangeOfTextView:dirtyRect]; 
    NSRange last = NSMakeRange(visible.location, 0); while (true) { 
     NSRange error = [appController rangeOfMisspelledWordInString:self.string onlyInRange:visible startingAt:last.location + last.length]; 
     last = error; 
     if (error.location == NSNotFound) { 
      break; 
     } 
     [arr addObject:[NSValue valueWithRange:error]]; 
    } 

    NSLog(@"Spellchecked"); 

    [[NSColor redColor] setStroke]; 
    CGFloat dash[] = {2.0f, 2.0f} ; 
    // Make the text ranges and mark them 
    for (NSValue *val in arr) { 
     NSRange range = [val rangeValue]; 
     NSRect rectInTextView = [self rectForCharacterRange:range]; 
     NSRect toDraw = rectInTextView; 
     NSBezierPath* aPath = [NSBezierPath bezierPath]; 
     [aPath setLineDash:dash count:2 phase:0]; 

     NSPoint lineStart = toDraw.origin; 
     lineStart.y += toDraw.size.height; 
     NSPoint lineEnd = lineStart; 
     lineEnd.x += toDraw.size.width; 

     [aPath moveToPoint:lineStart]; 
     [aPath lineToPoint:lineEnd]; 
     [aPath stroke];   
    }; 
    NSLog(@"Done");  
} 

堆栈跟踪:

Crashed Thread: 0 Dispatch queue: com.apple.main-thread 

Exception Type: EXC_CRASH (SIGABRT) 
Exception Codes: 0x0000000000000000, 0x0000000000000000 

Application Specific Information: 
objc[5751]: garbage collection is ON 
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSConcreteTextStorage attribute:atIndex:longestEffectiveRange:inRange:]: Range or index out of bounds' 
*** First throw call stack: 
(
    0 CoreFoundation      0x00007fff91387fc6 __exceptionPreprocess + 198 
    1 libobjc.A.dylib      0x00007fff8d4d7d5e objc_exception_throw + 43 
    2 CoreFoundation      0x00007fff91387dfa +[NSException raise:format:arguments:] + 106 
    3 CoreFoundation      0x00007fff91387d84 +[NSException raise:format:] + 116 
    4 AppKit        0x00000001005d842c -[NSConcreteTextStorage attribute:atIndex:longestEffectiveRange:inRange:] + 131 
    5 AppKit        0x00000001006288ec -[NSLayoutManager(NSPrivate) _drawBackgroundForGlyphRange:atPoint:parameters:] + 910 
    6 AppKit        0x00000001006277a2 -[NSTextView drawRect:] + 1913 
    7 Skrivest√∏tte      0x000000010000b56c Skrivest√∏tte + 46444 
    8 AppKit        0x0000000100626e66 -[NSTextView _drawRect:clip:] + 2545 
    9 AppKit        0x00000001004a985d -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3020 
    10 AppKit        0x00000001004aa34e -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5821 
    11 AppKit        0x00000001004aa34e -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5821 
    12 AppKit        0x00000001004a39af -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 4755 
    13 AppKit        0x000000010049c395 -[NSView displayIfNeeded] + 1528 
    14 AppKit        0x00000001004a1592 -[NSClipView _immediateScrollToPoint:] + 6533 
    15 AppKit        0x000000010049fb75 -[NSClipView scrollToPoint:] + 239 
    16 AppKit        0x000000010058f637 -[NSScrollView scrollClipView:toPoint:] + 266 
    17 AppKit        0x000000010058f3da -[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:] + 1497 
    18 AppKit        0x00000001005923b7 -[NSClipView _scrollTo:animate:] + 27 
    19 AppKit        0x0000000100bcd5a2 __-[NSScrollView _snapRubberBand]_block_invoke_2 + 1536 
    20 AppKit        0x0000000100b3fc4e ____NSPeriodicInvokerScheduled_block_invoke_2 + 53 
    21 libdispatch.dylib     0x00007fff907b98ba _dispatch_call_block_and_release + 18 
    22 libdispatch.dylib     0x00007fff907bbc07 _dispatch_after_timer_callback + 16 
    23 libdispatch.dylib     0x00007fff907be2b6 _dispatch_source_invoke + 635 
    24 libdispatch.dylib     0x00007fff907baf77 _dispatch_queue_invoke + 71 
    25 libdispatch.dylib     0x00007fff907bb6f7 _dispatch_main_queue_callback_4CF + 257 
    26 CoreFoundation      0x00007fff9131d06c __CFRunLoopRun + 1724 
    27 CoreFoundation      0x00007fff9131c676 CFRunLoopRunSpecific + 230 
    28 HIToolbox       0x00007fff93ab831f RunCurrentEventLoopInMode + 277 
    29 HIToolbox       0x00007fff93abf5c9 ReceiveNextEventCommon + 355 
    30 HIToolbox       0x00007fff93abf456 BlockUntilNextEventMatchingListInMode + 62 
    31 AppKit        0x000000010045ff5d _DPSNextEvent + 659 
    32 AppKit        0x000000010045f861 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135 
    33 AppKit        0x000000010045c19d -[NSApplication run] + 470 
    34 AppKit        0x00000001006dab88 NSApplicationMain + 867 
    35 Skrivest√∏tte      0x0000000100001020 Skrivest√∏tte + 4128 
    36 ???         0x0000000000000002 0x0 + 2 
) 
+0

你能看看是怎么回事: 35Skrivest√Πtte0x0000000 100001020Skrivest√Πtte+ 4128 –

+0

对不起,这是我的。出于某种原因,我没有象征崩溃报告的运气。 –

+0

首先尝试确定哪些使用的NSRanges导致异常。然后在异常情况下检查它的值。你的代码看起来不错,所以可能是无效的NSRange的原因在于它 – tomk

回答

0

我想你需要添加的断言功能检查 “范围”

NSRange range = [val rangeValue]; 

确保幅度不会NSNotFound

+1

虽然这不能伤害添加断言,我敢肯定填充arr屏蔽NSNotFound项目的代码。 –

1

*终止应用程序由于未捕获的异常 'NSRangeException',原因: '*

[NSConcreteTextStorage属性:atIndex:longestEffectiveRange:INRANGE:]:范围或索引超出范围'

这显然是一个NSRange例外,O”Ÿ说

+0

我认为真正的原因是范围超出了文本视图中文本的长度,因此从布局管理器请求矩形会导致崩溃。不过,谢谢你的建议。 –

相关问题