Tengo el siguiente código. Obtengo un SIGSEGV de vez en cuando. Tengo la sensación de que me falta algo sobre el manejo de la memoria usando bloques. ¿Es seguro pasar los Urs reemplazados, que se liberan automáticamente a este bloque? ¿Qué hay de modificar la variable de instancia formattedText?¿Qué está causando que un SIGSEGV use bloques?
NSMutableSet* replacedUrls = [[[NSMutableSet alloc] init] autorelease];
NSError *error = nil;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:
(NSTextCheckingTypeLink | NSTextCheckingTypePhoneNumber)
error:&error];
if (error) {
return;
}
[detector enumerateMatchesInString:self.formattedText
options:0
range:NSMakeRange(0, [self.formattedText length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
@try {
if (result.resultType == NSTextCheckingTypePhoneNumber) {
if (!result.phoneNumber) {
// not sure if this is possible
return;
}
self.formattedText = [self.formattedText stringByReplacingOccurrencesOfString:result.phoneNumber
withString:[NSString stringWithFormat:@"<a href=\"tel://%@\">%@</a>", result.phoneNumber, result.phoneNumber]];
}
else if (result.resultType == NSTextCheckingTypeLink) {
if (!result.URL) {
// not sure if this is possible
return;
}
NSString* fullUrl = [result.URL absoluteString];
if (!fullUrl) {
return;
}
if ([replacedUrls containsObject:fullUrl]) {
return;
}
// not sure if this is possible
if ([result.URL host] && [result.URL path]) {
NSString* urlWithNoScheme = [NSString stringWithFormat:@"%@%@", [result.URL host], [result.URL path]];
// replace all http://www.google.com to www.google.com
self.formattedText = [self.formattedText stringByReplacingOccurrencesOfString:fullUrl
withString:urlWithNoScheme];
// replace all www.google.com with http://www.google.com
NSString* replaceText = [NSString stringWithFormat:@"<a href=\"%@\">%@</a>", fullUrl, fullUrl];
self.formattedText = [self.formattedText stringByReplacingOccurrencesOfString:urlWithNoScheme
withString:replaceText];
[replacedUrls addObject:fullUrl];
}
}
}
@catch (NSException* ignore) {
// ignore any issues
}
}];
Después de leerlo, definitivamente estoy viendo dónde estaría creando un ciclo de retención ya que el yo se retendría. Sin embargo, aún no estoy seguro de cómo eso crearía el problema real. – tjg184
la línea más difícil es 'if (error) {return;} pero tampoco estoy seguro de cómo eso causa su problema (su código se recupera con gracia si regresa en este momento, ¿no?). Retener uno mismo no necesariamente causa un ciclo de retención, y un ciclo de retención no causaría un SIGSEGV; – hooleyhoop
Sí, esa línea es extraña. Ni siquiera estoy seguro de que sea necesario. Creo que lo agregué como un control de cordura. Estaba obteniendo un SIGSEGV antes de agregar esa línea. La mayoría de esas declaraciones se agregaron porque el informe de fallos solo apuntaba al bloque general y no a una línea específica. Es un poco molesto rastrear el problema. ¿Es seguro modificar el texto formateado en esto? – tjg184