Misterioso locking con el método NSString rangeOfComposedCharacterSequenceAtIndex:

Mi aplicación utiliza varios UITextView s, y recibimos un informe de locking de los usuarios que no podemos reproducir.

El informe de lockings no contiene ningún código y se bloquea con una NSInvalidArgumentException en el método rangeOfComposedCharacterSequenceAtIndex: que nuestro código no llama directamente sino que los frameworks parecen llamar.

Aquí está el informe del crash:

 0 CoreFoundation __exceptionPreprocess + 130 1 libobjc.A.dylib objc_exception_throw + 38 2 CoreFoundation -[NSException initWithCoder:] 3 Foundation -[NSString rangeOfComposedCharacterSequenceAtIndex:] + 88 4 UIKit __74-[UITextInputController _validCaretPositionFromCharacterIndex:downstream:]_block_invoke + 328 5 UIFoundation -[NSTextStorage coordinateReading:] + 36 6 UIKit -[UITextInputController _validCaretPositionFromCharacterIndex:downstream:] + 218 7 UIKit __52-[UITextInputController _characterPositionForPoint:]_block_invoke + 1112 8 UIFoundation -[NSLayoutManager(TextLocking) coordinateAccess:] + 46 9 UIKit -[UITextInputController _characterPositionForPoint:] + 224 10 UIKit -[UITextSelection setSelectionWithFirstPoint:secondPoint:] + 56 11 UIKit -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) twoFingerRangedSelectGesture:] + 386 12 UIKit _UIGestureRecognizerSendActions + 196 13 UIKit -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 1138 14 UIKit ___UIGestureRecognizerUpdate_block_invoke + 48 15 UIKit _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 218 16 UIKit _UIGestureRecognizerUpdate + 282 17 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 20 18 CoreFoundation __CFRunLoopDoObservers + 284 19 CoreFoundation __CFRunLoopRun + 730 20 CoreFoundation CFRunLoopRunSpecific + 522 21 CoreFoundation CFRunLoopRunInMode + 106 22 GraphicsServices GSEventRunModal + 138 23 UIKit UIApplicationMain + 1136 24 main.m line 16 25 libdyld.dylib start + 2 

( https://gist.github.com/timarnold/6981caa6a1ee2b98c2fe )

Como no sé exactamente qué parte de nuestro código está causando el locking, no estoy seguro de qué código de muestra sería útil publicar. Estoy más interesado en saber si alguien ha visto algo como esto, o podría tener una sugerencia sobre dónde o cómo investigar esto más.

Actualización el 21-11-2013

Pude reproducir este problema haciendo lo siguiente:

  • Agregue un poco de text a mi UITextView , incluido un carácter de línea nueva ( \n )
  • Obtenga mi aplicación para obligar a UITextView a renunciar al estado de primer respondedor
  • Obtenga mi aplicación para asignar el estado de primer respondedor a mi UITextView , y luego toque para insert el cursor al final de la cadena (alnetworkingedor de la location del nuevo carácter)

después de lo cual la aplicación se bloqueó con el informe anterior.

UITextView crear esto en un proyecto Xcode vacío con solo un stock UITextView y nada más, y no UITextView hacerlo. Parece que hay algo sucediendo en mi aplicación que conspira con UITextView para que ocurra este locking. Me encantaría saber qué, pero el problema se resuelve para mí en este proyecto (ya que no nos interesa rastrear caracteres de nueva línea, y podemos recortarlos, evitando que se produzcan lockings).

Si alguien puede reproducir esto en un proyecto de muestra, sería genial archivar un radar si este es un error con UITextView .

Gracias a @ wattson12 y @Johan Kool por las respuestas que llevaron a una solución.

Hoy tuve el mismo problema, no tengo un dispositivo antiguo, pero sería interesante ver si esto es diferente en <7.0.3, ya que ahora es muy reproducible y no se recogió antes. Realmente no puedo explicar el por qué, pero aquí es lo que noté y la solución que utilicé:

Vi que tocar en una vista de text se bloqueaba cuando:

  • Tenía un nuevo carácter de línea al final del text y
  • Hice tapping en alguna parte fuera del text actual

Mi solución fue recortar la nueva línea desde el final (utilicé un ciclo while para evitar eliminar cualquier carácter de línea nueva pero stringByTrimmingCharactersInSet estaría bien si eso no fuera un problema)

Configurar scrollEnabled en YES (pnetworkingeterminado) solucionó el locking para nosotros. Necesitábamos scrollEnabled para ser NO para la interfaz de usuario. Pero una UI subóptima es mejor que un locking, por lo que este método de categoría lo habilita solo para versiones de iOS inferiores a 7.1

 - (void)enableScrollIfBuggyOSVersion { if ([[[UIDevice currentDevice] systemVersion] compare:@"7.1" options:NSNumericSearch] == NSOrdenetworkingAscending) { [self setScrollEnabled:YES]; } else { [self setScrollEnabled:NO]; } }