【问题标题】:UITextField textInputView message sent to deallocated instanceUITextField textInputView 消息发送到释放的实例
【发布时间】:2016-03-01 05:49:10
【问题描述】:

点击 UITextField 时发生崩溃。我有两个控制器,比如说 A 和 B。当我在控制器 A 中模态显示控制器 B 时,点击 UITextField 一切正常。然后我解散控制器 B,并再次展示它。这次当我点击 UITextField 时发生崩溃。当我在我的方案中启用 NSZombie 时,出现崩溃消息 - -[UITextField textInputView]: message sent to deallocated instance。

我没有在 UITextField 上设置 UITextFieldDelegate。当我尝试使用 Instruments -> Zombies 进行调试时,双击某个发布/保留历史行时没有源代码(不可用)。

我的方案的构建配置是Debug。 Xcode 版本为 7.2.1。崩溃仅在 iOS 8 上发生。iOS 9 很好。

PS:当我尝试重新符号化应用程序时,我发现缺少一个 System Frameworks dyld。然后我按下 Locate 按钮并打开我的调试应用程序的 dsym 文件,但出现错误消息 “指定的路径没有为任何选定的图书馆。”

更新 1:

一个控制器:

#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!";,没有崩溃。只有当我平移/触摸UITextField 或调用[self.textField becomeFirstResponder]; 时它才会崩溃。

【问题讨论】:

  • 您的 A 是否对 B 的文本字段有强引用?您是否尝试在 B 的 dealloc 中将文本字段的委托设置为 nil?
  • 您是否在控制器 A 中创建到您的 UITextField 的任何连接?
  • 不,@property (weak, nonatomic) IBOutlet UITextField *textField; 与控制器 A 没有任何连接
  • A 和 B 之间的唯一连接是与一些标识符进行 segue,它以模态方式显示我的控制器 B
  • 可以把你的A和B的头文件贴出来了解一下吗?

标签: ios objective-c nszombie


【解决方案1】:

最后,我找到了崩溃的原因。我有一个名为 UITextField (AutoSuggestion) 的 UITextField 扩展名,我在其中调用了 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 后,方法崩溃消失了。因此我决定寻找新的方法来实现自动建议功能。

有趣的是我没有在任何地方的代码中导入头文件,但发生了崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 2016-08-28
    • 2011-06-16
    • 2013-08-30
    相关资源
    最近更新 更多