发送到释放实例的 UITextField textInputView 消息
UITextField textInputView message sent to deallocated instance
我在点击 UITextField 时发生崩溃。我有两个控制器,比方说 A 和 B。当我在控制器 A 中模态显示控制器 B 并点击 UITextField 时,一切正常。然后我关闭控制器 B,并再次呈现它。这次当我单击 UITextField 时发生崩溃。当我在我的方案中启用 NSZombie 时,出现崩溃消息 - -[UITextField textInputView]: message sent to deallocated instance
.
我没有在 UITextField 上设置 UITextFieldDelegate
。当我尝试使用 Instruments -> Zombies 进行调试时,双击某些 release/retain 历史记录行时没有源代码(不可用)。
我的方案的构建配置是调试。 Xcode 版本为 7.2.1。崩溃仅在 iOS 8 上发生。 iOS 9 没问题。
PS:当我尝试重新符号化应用程序时,我发现缺少一个 System Frameworks dyld。然后我按 Locate 按钮并打开我的调试应用程序的 dsym 文件,但出现错误消息 "The specified path didn't locate a dSYM for any of the selected libraries."
更新 1:
A控制器:
#import <UIKit/UIKit.h>
@interface A : UIViewController
@end
#import "A.h"
#import "RoundedButton.h"
@interface A ()
@property (weak, nonatomic) IBOutlet RoundedButton *signInButton;
@end
@implementation A
- (void)viewDidLoad {
[super viewDidLoad];
[self configUI];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"signIn"]) {
}
}
#pragma mark - Config UI
- (void)configUI {
// setup ui
}
- (void)dealloc {
NSLog(@"%@ deallocated", NSStringFromClass([self class]));
}
@end
B 控制器:
#import <UIKit/UIKit.h>
@interface B : UIViewController
@end
#import "B.h"
#import "SKFormTextField.h"
#import "RoundedButton.h"
@interface B ()
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet RoundedButton *signInButton;
@end
@implementation B {
SKAlertView *alertView;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self configUI];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
#pragma mark - Actions
- (IBAction)cancelSignIn:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Config UI
- (void)configUI {
self.navigationController.navigationBarHidden = YES;
self.textField.secureTextEntry = true;
self.textField.autocorrectionType = UITextAutocorrectionTypeNo;
}
- (void)dealloc {
NSLog(@"%@ deallocated", NSStringFromClass([self class]));
}
@end
更新 2:
当我调用 UITextField
时,与 self.textField.text = @"Hello, World!";
一样,没有崩溃。只有当我 pan/touch UITextField
或调用 [self.textField becomeFirstResponder];
时它才会崩溃。
终于,我找到了崩溃的原因。我有 UITextField
名为 UITextField (AutoSuggestion)
的扩展,我在其中调用了 dealloc 方法来删除自己的观察者。
代码示例:
/* .h file */
#import <UIKit/UIKit.h>
// some protocol
@interface UITextField (AutoSuggestion)
// some properties and methods
@end
/* .m file */
#import "UITextField+AutoSuggestion.h"
#import <objc/runtime.h>
@implementation UITextField (AutoSuggestion)
- (void)observeTextFieldChanges {
self.layer.masksToBounds = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toggleAutoSuggestion:) name:UITextFieldTextDidChangeNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideAutoSuggestion) name:UITextFieldTextDidEndEditingNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getKeyboardHeight:)
name:UIKeyboardDidShowNotification
object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidEndEditingNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
}
// other methods
@end
在我删除 dealloc
方法后崩溃消失了。因此我决定寻找新的方法来实现自我暗示功能。
有趣的是,我没有在代码中任何地方导入头文件,而是发生了崩溃。
我在点击 UITextField 时发生崩溃。我有两个控制器,比方说 A 和 B。当我在控制器 A 中模态显示控制器 B 并点击 UITextField 时,一切正常。然后我关闭控制器 B,并再次呈现它。这次当我单击 UITextField 时发生崩溃。当我在我的方案中启用 NSZombie 时,出现崩溃消息 - -[UITextField textInputView]: message sent to deallocated instance
.
我没有在 UITextField 上设置 UITextFieldDelegate
。当我尝试使用 Instruments -> Zombies 进行调试时,双击某些 release/retain 历史记录行时没有源代码(不可用)。
我的方案的构建配置是调试。 Xcode 版本为 7.2.1。崩溃仅在 iOS 8 上发生。 iOS 9 没问题。
PS:当我尝试重新符号化应用程序时,我发现缺少一个 System Frameworks dyld。然后我按 Locate 按钮并打开我的调试应用程序的 dsym 文件,但出现错误消息 "The specified path didn't locate a dSYM for any of the selected libraries."
更新 1:
A控制器:
#import <UIKit/UIKit.h>
@interface A : UIViewController
@end
#import "A.h"
#import "RoundedButton.h"
@interface A ()
@property (weak, nonatomic) IBOutlet RoundedButton *signInButton;
@end
@implementation A
- (void)viewDidLoad {
[super viewDidLoad];
[self configUI];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleDefault;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"signIn"]) {
}
}
#pragma mark - Config UI
- (void)configUI {
// setup ui
}
- (void)dealloc {
NSLog(@"%@ deallocated", NSStringFromClass([self class]));
}
@end
B 控制器:
#import <UIKit/UIKit.h>
@interface B : UIViewController
@end
#import "B.h"
#import "SKFormTextField.h"
#import "RoundedButton.h"
@interface B ()
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet RoundedButton *signInButton;
@end
@implementation B {
SKAlertView *alertView;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self configUI];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
#pragma mark - Actions
- (IBAction)cancelSignIn:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Config UI
- (void)configUI {
self.navigationController.navigationBarHidden = YES;
self.textField.secureTextEntry = true;
self.textField.autocorrectionType = UITextAutocorrectionTypeNo;
}
- (void)dealloc {
NSLog(@"%@ deallocated", NSStringFromClass([self class]));
}
@end
更新 2:
当我调用 UITextField
时,与 self.textField.text = @"Hello, World!";
一样,没有崩溃。只有当我 pan/touch UITextField
或调用 [self.textField becomeFirstResponder];
时它才会崩溃。
终于,我找到了崩溃的原因。我有 UITextField
名为 UITextField (AutoSuggestion)
的扩展,我在其中调用了 dealloc 方法来删除自己的观察者。
代码示例:
/* .h file */
#import <UIKit/UIKit.h>
// some protocol
@interface UITextField (AutoSuggestion)
// some properties and methods
@end
/* .m file */
#import "UITextField+AutoSuggestion.h"
#import <objc/runtime.h>
@implementation UITextField (AutoSuggestion)
- (void)observeTextFieldChanges {
self.layer.masksToBounds = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toggleAutoSuggestion:) name:UITextFieldTextDidChangeNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideAutoSuggestion) name:UITextFieldTextDidEndEditingNotification object:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getKeyboardHeight:)
name:UIKeyboardDidShowNotification
object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidEndEditingNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidShowNotification object:nil];
}
// other methods
@end
在我删除 dealloc
方法后崩溃消失了。因此我决定寻找新的方法来实现自我暗示功能。
有趣的是,我没有在代码中任何地方导入头文件,而是发生了崩溃。