gpt4 book ai didi

ios - 使用 self.delegate 子类化 UITextField 会导致应用程序卡住,CPU 峰值达到 100%

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:17:03 26 4
gpt4 key购买 nike

我有一个 UITextField 的子类,它设置了 self.delegate = self。该子类用于防止将特殊字符输入到 UITextField 中。起初它工作正常,但在按下几个键后,CPU 峰值达到 100% 并卡住了应用程序。 Xcode 中没有崩溃日志,因为该应用程序从未真正崩溃过,它只是保持卡住状态,直到我停止它。经过一些研究,我确定问题是将 delegate 设置为 self - 显然我应该为 UITextField 创建一个单独的 delegate ?我在网上搜索过,但找不到任何关于如何执行此操作的有用信息。

我的 AcceptedCharacters 子类:

AcceptedCharacters.h

#import <UIKit/UIKit.h>

@interface AcceptedCharacters : UITextField <UITextFieldDelegate>

@end

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 *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];

return [string isEqualToString:filtered];
}

@end

Xcode CPU Report

我在堆栈溢出中发现的类似问题:

Application freezes after editing custom UITextField

UITextField delegate jumping to 100% CPU usage and crashing upon using keyboard shortcut

Why does UITextField lock up when setting itself to delegate

我已经通读了这些解决方案,但对于初学者来说它们非常模糊。我将非常感谢有人在下面修改我的代码,甚至为我指明教程或文档的方向?提前致谢。

编辑:

我已经在我的一个 ViewControllers 上测试了这段代码,当它符合 UITextFieldDelegate 协议(protocol)并且当我的文本字段 delegates 是设置为 self(参见下面的代码片段)。

在我的 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;

我宁愿创建 UITextField 的几个子类并在特定的文本字段上调用它们,也不愿使用像下面这样的困惑方法。

#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 *filtered = [[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 *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
return (([string isEqualToString:filtered])&&(newLength <= CHARACTER_LIMIT));
}
//return YES;
return [string isEqualToString:filtered];
}

最佳答案

试试这个:

@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 *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];

return [string isEqualToString:filtered];
}
@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

然后将您的 View Controller 指定为委托(delegate)并在您的 View Controller 中:

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

关于ios - 使用 self.delegate 子类化 UITextField 会导致应用程序卡住,CPU 峰值达到 100%,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26488228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com