2012-05-25 24 views
10

Một số người dùng của tôi đang gặp sự cố này. Theo như tôi có thể nói, bằng cách nào đó nó được kết nối với phương pháp -drawRect: của phân lớp NSTextView của tôi, nhưng tôi không thể thấy điều gì có thể gây ra nó và kiểm tra căng thẳng đã không thể loại bỏ lỗi này.Sụp đổ trong drawRect - nguyên nhân gây ra nó?

Mã cho 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");  
} 

Stack trace:

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

bạn có thể nhìn vào những gì đang xảy ra ở đây: 35 Skrivest√Πtte 0x0000000 100001020 Skrivest√∏tte + 4128 –

+0

Xin lỗi, đây là những gì tôi có. Tôi đã không có may mắn tượng trưng cho báo cáo sự cố vì một lý do nào đó. –

+0

Trước tiên, hãy cố gắng ghim xuống NSRanges đã sử dụng nào gây ra ngoại lệ. Sau đó kiểm tra giá trị của nó trong trường hợp ngoại lệ. Mã của bạn trông ok, vì vậy có lẽ lý do cho NSRange không hợp lệ nằm bên ngoài nó – tomk

Trả lời

0

tôi nghĩ rằng bạn cần thêm chức năng khẳng định để kiểm tra "phạm vi"

NSRange range = [val rangeValue]; 

đảm bảo phạm vi sẽ không được NSNotFound.

+1

Trong khi đó không thể làm tổn thương để thêm khẳng định, tôi khá chắc chắn mã mà populates arr màn hình ra các mục NSNotFound. –

1

* Chấm dứt ứng dụng do ngoại lệ còn tự do 'NSRangeException', lý do: '*

[NSConcreteTextStorage thuộc tính: atIndex: longestEffectiveRange: inRange:]: Dải hoặc chỉ số nằm ngoài giới hạn'

Đó rõ ràng là một ngoại lệ NSRange, như O' y nói

+0

Tôi nghĩ rằng nguyên nhân thực sự là phạm vi vượt quá độ dài của văn bản trong chế độ xem văn bản và do đó yêu cầu hình chữ nhật cho nó từ trình quản lý bố cục bị treo. Tuy nhiên, cảm ơn bạn đã đề xuất của bạn. –

Các vấn đề liên quan