2012-05-25 169 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

我認爲真正的原因是範圍超出了文本視圖中文本的長度,因此從佈局管理器請求矩形會導致崩潰。不過,謝謝你的建議。 –

相關問題