objective-c – 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
)

解决方法

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

[NSConcreteTextStorage attribute:atIndex:longestEffectiveRange:inRange:]: Range or index out of bounds’

这显然是一个NSRange异常,正如O’y所说

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...