2012-05-25 8 views
10

Algunos de mis usuarios están recibiendo este bloqueo.Fallo en drawRect - ¿qué lo causa?

Por lo que puedo decir, de alguna manera está conectado al método -drawRect: de mi NSTextView subclasificado, pero no puedo ver lo que podría causarlo, y la prueba de estrés no ha podido sacudir el error.

Código de 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");  
} 

Seguimiento de la pila:

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

¿Puede ver lo que está pasando aquí: 35 Skrivest√Πtte 0x0000000 100001020 Skrivest√Πtte + 4128 –

+0

Lo siento, esto es lo que tengo. No he tenido suerte simbolizando el informe de fallas por alguna razón. –

+0

Primero intente determinar cuál de los NSRanges utilizados causa la excepción. Luego verifique sus valores en caso de la excepción. Su código se ve bien, por lo que probablemente el motivo del NSRange no válido se encuentre fuera de él – tomk

Respuesta

0

creo que es necesario añadir la función de aserción para comprobar la "gama"

NSRange range = [val rangeValue]; 

asegúrese de rango no será NSNotFound.

+1

Si bien no puede doler agregar la afirmación, estoy bastante seguro de que el código que puebla filtra pantallas los elementos NSNotFound. –

1

* Terminación de aplicación debido a excepción no detectada 'NSRangeException', razón: '*

[atributo NSConcreteTextStorage: atIndex: longestEffectiveRange: inRange:]: Rango o índice fuera de límites'

es claramente una excepción NSRange, como O' y dijo

+0

Creo que la verdadera causa es que el rango va más allá de la longitud del texto en la vista de texto, y por lo tanto, se bloquea el rectángulo que lo solicita. Aún así, gracias por tu sugerencia. –

Cuestiones relacionadas