当处理程序块执行时,UIAlertController 为 nil
UIAlertController is nil when handler block executes
这是前面的问题: 我有一个带有文本字段的 UIAlertController。当用户触摸警报中的 "Confirm" 按钮时,我想将该文本字段的内容保存为 NSString。但是,当执行 Confirm 操作块时,警报为零(大概在那时已经解除并解除分配),因此它的文本字段也是如此,这意味着我无法保存文本字段的文本。
我正在使用一系列 UIAlertControllers 来允许用户为我的应用程序创建密码,这样每当应用程序进入前台时,系统都会提示用户输入密码,然后才能使用该应用程序。
我创建了一个 UIAlertController 类别,其中包含几个方便的方法,return 预配置了我需要使用的警报。这是其中之一:
+ (UIAlertController*)passcodeCreationAlertWithConfirmBehavior:(void(^)())confirmBlock andCancelBehavior:(void(^)())cancelBlock {
UIAlertController *passcodeCreationAlert = [UIAlertController alertControllerWithTitle:@"Enter a passcode"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[passcodeCreationAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.keyboardType = UIKeyboardTypeNumberPad;
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
if (cancelBlock) {
cancelBlock();
}
}];
UIAlertAction* confirmAction = [UIAlertAction actionWithTitle:@"Confirm"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (confirmBlock) {
confirmBlock();
}
}];
[passcodeCreationAlert addAction:cancelAction];
[passcodeCreationAlert addAction:confirmAction];
passcodeCreationAlert.preferredAction = confirmAction;
confirmAction.enabled = NO;
return passcodeCreationAlert;
}
此方法 return 是一个 UIAlertController,允许用户在文本字段中输入他们想要的密码。当我在视图控制器中调用此方法时,我将块作为参数传递,用作 UIAlertAction 处理程序:
- (void)presentCreatePasscodeAlert {
UIAlertController *alert = [UIAlertController passcodeCreationAlertWithConfirmBehavior:^{
firstPasscode = alert.textFields[0].text;
[self presentConfirmPasscodeAlert];
} andCancelBehavior:^{
[self presentEnablePasscodeAlert];
}];
alert.textFields[0].delegate = self;
[self presentViewController:alert animated:YES completion:nil];
}
现在有更多的上下文来重申这个问题:当在行中输入操作块时:
firstPasscode = alert.textFields[0].text;
警报为零,其文本字段也是零,这意味着我无法保存文本字段的文本。
然而,在一个单独的项目中,我尝试在不使用类别和自定义便利方法的情况下获得相同的功能,并且效果如愿:
- (void) createPassword {
UIAlertController *createPasswordAlert = [UIAlertController alertControllerWithTitle:@"Enter a password"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
__weak ViewController *weakSelf = self;
[createPasswordAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.delegate = weakSelf;
textField.keyboardType = UIKeyboardTypeNumberPad;
}];
UIAlertAction* confirmAction = [UIAlertAction actionWithTitle:@"Confirm"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
self.password = createPasswordAlert.textFields[0].text;
[self confirmPassword];
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self promptPasswordCreation];
}];
[createPasswordAlert addAction:confirmAction];
[createPasswordAlert addAction:cancelAction];
confirmAction.enabled = NO;
[self presentViewController:createPasswordAlert animated:YES completion:nil];
}
果然,在上面的代码中,当输入确认块时,警报存在,我可以保存文本。
我是否通过将块作为参数传递给我的便捷方法做了一些奇怪的事情?
您的一个问题是,当您创建块并将其发送到初始化程序时,您正在引用块内的 nil
对象。然后该块与该 nil
引用一起保存并作为块传递给您的处理程序。
UIAlertController *alert = [UIAlertController passcodeCreationAlertWithConfirmBehavior:^{
firstPasscode = alert.textFields[0].text;
[self presentConfirmPasscodeAlert];
} andCancelBehavior:^{
[self presentEnablePasscodeAlert];
}];
当您创建该块并将其发送以进行保存时,其中 alert
尚未初始化。修复该问题的一个选项是使用标准初始化器,然后对方法进行分类以添加所需的块函数。另一种选择可能是尝试将 __block
修饰符添加到 alert
对象,尽管我认为这不会有帮助。
这是前面的问题: 我有一个带有文本字段的 UIAlertController。当用户触摸警报中的 "Confirm" 按钮时,我想将该文本字段的内容保存为 NSString。但是,当执行 Confirm 操作块时,警报为零(大概在那时已经解除并解除分配),因此它的文本字段也是如此,这意味着我无法保存文本字段的文本。
我正在使用一系列 UIAlertControllers 来允许用户为我的应用程序创建密码,这样每当应用程序进入前台时,系统都会提示用户输入密码,然后才能使用该应用程序。
我创建了一个 UIAlertController 类别,其中包含几个方便的方法,return 预配置了我需要使用的警报。这是其中之一:
+ (UIAlertController*)passcodeCreationAlertWithConfirmBehavior:(void(^)())confirmBlock andCancelBehavior:(void(^)())cancelBlock {
UIAlertController *passcodeCreationAlert = [UIAlertController alertControllerWithTitle:@"Enter a passcode"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[passcodeCreationAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.keyboardType = UIKeyboardTypeNumberPad;
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
if (cancelBlock) {
cancelBlock();
}
}];
UIAlertAction* confirmAction = [UIAlertAction actionWithTitle:@"Confirm"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (confirmBlock) {
confirmBlock();
}
}];
[passcodeCreationAlert addAction:cancelAction];
[passcodeCreationAlert addAction:confirmAction];
passcodeCreationAlert.preferredAction = confirmAction;
confirmAction.enabled = NO;
return passcodeCreationAlert;
}
此方法 return 是一个 UIAlertController,允许用户在文本字段中输入他们想要的密码。当我在视图控制器中调用此方法时,我将块作为参数传递,用作 UIAlertAction 处理程序:
- (void)presentCreatePasscodeAlert {
UIAlertController *alert = [UIAlertController passcodeCreationAlertWithConfirmBehavior:^{
firstPasscode = alert.textFields[0].text;
[self presentConfirmPasscodeAlert];
} andCancelBehavior:^{
[self presentEnablePasscodeAlert];
}];
alert.textFields[0].delegate = self;
[self presentViewController:alert animated:YES completion:nil];
}
现在有更多的上下文来重申这个问题:当在行中输入操作块时:
firstPasscode = alert.textFields[0].text;
警报为零,其文本字段也是零,这意味着我无法保存文本字段的文本。
然而,在一个单独的项目中,我尝试在不使用类别和自定义便利方法的情况下获得相同的功能,并且效果如愿:
- (void) createPassword {
UIAlertController *createPasswordAlert = [UIAlertController alertControllerWithTitle:@"Enter a password"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
__weak ViewController *weakSelf = self;
[createPasswordAlert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.delegate = weakSelf;
textField.keyboardType = UIKeyboardTypeNumberPad;
}];
UIAlertAction* confirmAction = [UIAlertAction actionWithTitle:@"Confirm"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
self.password = createPasswordAlert.textFields[0].text;
[self confirmPassword];
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self promptPasswordCreation];
}];
[createPasswordAlert addAction:confirmAction];
[createPasswordAlert addAction:cancelAction];
confirmAction.enabled = NO;
[self presentViewController:createPasswordAlert animated:YES completion:nil];
}
果然,在上面的代码中,当输入确认块时,警报存在,我可以保存文本。
我是否通过将块作为参数传递给我的便捷方法做了一些奇怪的事情?
您的一个问题是,当您创建块并将其发送到初始化程序时,您正在引用块内的 nil
对象。然后该块与该 nil
引用一起保存并作为块传递给您的处理程序。
UIAlertController *alert = [UIAlertController passcodeCreationAlertWithConfirmBehavior:^{
firstPasscode = alert.textFields[0].text;
[self presentConfirmPasscodeAlert];
} andCancelBehavior:^{
[self presentEnablePasscodeAlert];
}];
当您创建该块并将其发送以进行保存时,其中 alert
尚未初始化。修复该问题的一个选项是使用标准初始化器,然后对方法进行分类以添加所需的块函数。另一种选择可能是尝试将 __block
修饰符添加到 alert
对象,尽管我认为这不会有帮助。