Subclass UITextField con self.demand causa que la aplicación se congele, la CPU sube al 100%

Tengo una subclass de UITextField que establece self.delegate = self . La subclass se usa para evitar que se introduzcan caracteres especiales en un UITextField . Al principio funciona bien, pero después de presionar algunas teclas, la CPU sube al 100% y congela la aplicación. No hay un logging de lockings en Xcode porque la aplicación nunca se cuelga, simplemente permanece congelada hasta que la detengo. Después de un poco de investigación, he determinado que el problema es establecer el delegate en self : ¿aparentemente debería hacer un delegate separado para UITextField ? He buscado en línea pero no puedo encontrar nada útil sobre cómo hacer esto.

Mi subclass de caracteres aceptados:

 AcceptedCharacters.h #import <UIKit/UIKit.h> @interface AcceptedCharacters : UITextField <UITextFieldDelegate> @end 

Y

 AcceptedCharacters.m #import "AcceptedCharacters.h" #define ACCEPTABLE_CHARACTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_." @implementation AcceptedCharacters - (void)awakeFromNib { [super awakeFromNib]; if (self) { self.delegate = self; } } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { //NSLog(@"AcceptedCharacters"); // Restrict special characters NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet]; NSString *filtenetworking = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; return [string isEqualToString:filtenetworking]; } @end 

Informe de la CPU Xcode

Preguntas similares que he encontrado en el desbordamiento de stack:

La aplicación se congela después de editar el UITextField personalizado.

El delegado de UITextField saltó al 100% de uso de la CPU y se bloqueó al usar el método abreviado de keyboard

¿Por qué UITextField se bloquea al configurarse para delegar

He leído las soluciones, pero son bastante vagas para un principiante. Le agradecería mucho a alguien que modifique mi código a continuación o que incluso me señale en la dirección de un tutorial o documentation. Gracias por adelantado.

EDITAR:

He probado este código en uno de mis ViewControllers y funciona bien cuando se ajusta al protocolo UITextFieldDelegate y cuando mis delegates están configurados en self (ver el fragment a continuación).

En mi método viewDidLoad :

 self.forenameField.delegate = self; self.surnameField.delegate = self; self.addLine1Field.delegate = self; self.addLine2Field.delegate = self; self.addLine3Field.delegate = self; self.addLine4Field.delegate = self; self.addLine5Field.delegate = self; self.postcodeField.delegate = self; self.telLandField.delegate = self; self.telMobField.delegate = self; self.emailField.delegate = self; self.dobField.delegate = self; self.niNumField.delegate = self; 

Prefiero crear varias subclasss de UITextField y llamarlas en campos de text específicos en lugar de tener un método desorderado como el que se muestra a continuación.

 #define ACCEPTABLE_CHARACTERS @" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_." #define NUMBERS_ONLY @"1234567890" #define CHARACTER_LIMIT 11 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // Restrict special characters NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet]; NSString *filtenetworking = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; // Convert postcode field characters to uppercase if (textField == self.postcodeField) { [textField setText:[textField.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]]; return NO; } // Set max character limit on tel fields if (textField == self.telMobField || textField == self.telLandField) { NSUInteger newLength = [textField.text length] + [string length] - range.length; NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:NUMBERS_ONLY] invertedSet]; NSString *filtenetworking = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; return (([string isEqualToString:filtenetworking])&&(newLength <= CHARACTER_LIMIT)); } //return YES; return [string isEqualToString:filtenetworking]; } 

Prueba esto:

 @interface MyTextField : UITextField - (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range; @end @implementation MyTextField - (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range { NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:ACCEPTABLE_CHARACTERS] invertedSet]; NSString *filtenetworking = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; return [string isEqualToString:filtenetworking]; } @end @interface PostalCodeTextField : MyTextField @end @implementation PostalCodeTextField - (BOOL)stringIsAcceptable:(NSString *)string inRange:(NSRange)range { [self setText:[self.text stringByReplacingCharactersInRange:range withString:[string uppercaseString]]]; return NO; } @end .. more subclasses 

Luego asigne su controller de vista como delegado y en su controller de vista:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if ([textField isKindOfClass:[MyTextField class]]) { return [(MyTextField *)textField stringIsAcceptable:string inRange:range]; } return YES; }