drawRect崩溃 - 是什么原因引起的?

时间:2012-05-25 15:46:16

标签: objective-c macos

我的一些用户正在遭遇此次崩溃。

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

drawRect的代码

NSTextView

堆栈追踪:

- (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");    
}

2 个答案:

答案 0 :(得分:1)

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

  

[NSConcreteTextStorage属性:atIndex:longestEffectiveRange:inRange:]:范围或索引越界'

显然是一个NSRange例外,正如O'y所说

答案 1 :(得分:0)

我认为你需要添加断言功能来检查“范围”

NSRange range = [val rangeValue];

确保范围不是NSNotFound