ios - inputAssistantItem 和 inputAccessoryView 停止使用 ARC

标签 ios automatic-ref-counting uitextinput

我正在使用此代码在我的 iOS 应用程序的屏幕键盘上方添加一些按钮。请注意,我在手机和 iOS 9 之前的设备上使用较旧的 inputAccessoryView 方法,在 iOS 9 平板电脑上使用较新的 inputAssistantItem:

UITextView *textInputMultiline = [[UITextView alloc] initWithFrame:frame];
TextInputToolbar *textInputToolbar = [TextInputToolbar alloc]; // custom class
(void)[textInputToolbar initWithNibName:@"TextInputToolbar" bundle:nil];
textInputToolbar.textView = textInputMultiline;
if ((self.appDelegate.isTablet)&&([[[UIDevice currentDevice] systemVersion] compare:@"9.0"] != NSOrderedAscending)) {
    NSMutableArray *barButtonItems = [NSMutableArray array];
    [barButtonItems addObject:[[UIBarButtonItem alloc] initWithTitle:@"button 1" style:UIBarButtonItemStylePlain target:textInputToolbar action:@selector(button1)]];
    [barButtonItems addObject:[[UIBarButtonItem alloc] initWithTitle:@"button 2" style:UIBarButtonItemStylePlain target:textInputToolbar action:@selector(button2)]];
    [barButtonItems addObject:[[UIBarButtonItem alloc] initWithTitle:@"button 3" style:UIBarButtonItemStylePlain target:textInputToolbar action:@selector(button3)]];
    UIBarButtonItem *representativeItem = nil;
    UIBarButtonItemGroup *group = [[UIBarButtonItemGroup alloc] initWithBarButtonItems:barButtonItems representativeItem:representativeItem];
    textInputMultiline.inputAssistantItem.trailingBarButtonGroups = [NSArray arrayWithObject:group];
} else {
    textInputMultiline.inputAccessoryView = textInputToolbar.view;
}

我的自定义工具栏类如下所示:

@interface TextInputToolbar : UIViewController {
    UITextView *textView;

    IBOutlet UIButton *button1;
    IBOutlet UIButton *button2;
    IBOutlet UIButton *button3;
}

@property (nonatomic, strong) UITextView *textView;

- (void)insertText:(NSString *)text;

- (IBAction)button1;
- (IBAction)button2;
- (IBAction)button3;

@end

还有……

#import "TextInputToolbar.h"

@implementation TextInputToolbar

@synthesize textView;

- (void)viewDidLoad {
    NSLog(@"viewDidLoad");
    [super viewDidLoad];
}

- (void)insertText:(NSString *)text {
    [self.textView insertText:text];
}

- (IBAction)button1 {
    NSLog(@"button1");
    [self insertText:@"1"];
}

- (IBAction)button2 {
    NSLog(@"button2");
    [self insertText:@"2"];
}

- (IBAction)button3 {
    NSLog(@"button3");
    [self insertText:@"3"];
}

@end

当我的应用未使用 ARC 时,这按预期工作。我最近更新到 ARC,它只需要对上面的代码进行最小的更改(我以前在 UIBarButtonItems 上有自动释放,并且没有 (void)initWithNibName),现在按钮仍按预期显示,但不起作用。在 iOS 8 上,我在点击其中一个按钮时发生崩溃([CALayer button1]: unrecognized selector sent to instance,我认为这表示无效的内存指针),而在 iOS 9 上,没有任何反应当我点击一个按钮时,按钮方法中的日志记录不会被调用。

在更新到 ARC 之前,我有一个项目副本,当我返回并在我的 iOS 8 或 iOS 9 设备上运行该项目时,工具栏按钮再次起作用。所以看起来 ARC 要么是问题的根源,要么是另一个问题的触发因素。

如果我将 barButtonItem 指向自己,就像这样......

[barButtonItems addObject:[[UIBarButtonItem alloc] initWithTitle:@"button 3" style:UIBarButtonItemStylePlain target:self action:@selector(test)]];

...按预期收到方法调用。如果我将 barButtonItem 选择器更改为无效方法,就像这样...

[barButtonItems addObject:[[UIBarButtonItem alloc] initWithTitle:@"button 3" style:UIBarButtonItemStylePlain target:textInputToolbar action:@selector(flkjfd)]];

...没有任何反应。这向我暗示,当按钮选择器被调用时,textInputToolbar 不知何故变成了 nil,因为如果它不是 nil,这将导致无法识别的选择器崩溃。

但我知道 TextInputToolbar 类及其 View 正在加载,因为在 viewDidLoad 中发生了登录,并且因为该 View 显示为手机和 iOS 8 平板电脑的 inputAccessoryView。

知道发生了什么,或者我还能做些什么来解决问题?

最佳答案

您的代码从来都不是正确的,只是因为泄漏才起作用。你基本上失去/不保留 View Controller 。它曾经只是继续存在和工作,但在 ARC 下它被释放了,所以没有什么可以响应按钮。 ARC 已经解决了您的内存问题,并让您意识到存在问题,尽管不是以一种理想的方式。

要修复,请在使用 View 时保留 View Controller 。

另外,我不确定你是从哪里学来的:

TextInputToolbar *textInputToolbar = [TextInputToolbar alloc]; // custom class
(void)[textInputToolbar initWithNibName:@"TextInputToolbar" bundle:nil];

但你不应该。在一条线上完成所有操作。不要忽略从 init 调用返回的对象 - 它可能与您最初调用它的对象不同。

关于ios - inputAssistantItem 和 inputAccessoryView 停止使用 ARC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38285171/

相关文章:

objective-c - 使用 GestureRecognizers 操作 UIImage - NOT UIImageView

ios - 使用 CoreGraphics 在 IOS 中使用交叉影线?

ios - ARC 实例变量保留释放

ios - Rafactor 在项目中只有一个文件使用 ARC?

ios - UITextInput 仅在 iOS 9 中返回 nil 位置

ios - 处理 iOS 键盘上的标记文本

ios - UITextField 开始听写

UIButton 上的 iOS NSAttributedString

ios - iOS "Exclamation"角标(Badge)/按钮是否可在应用程序中使用?

objective-c - 保持对象事件直到后台任务完成