2016-07-09 8 views
0

このコードを使用して、iOSアプリケーションのオンスクリーンキーボードの上にボタンを追加しています。私はiOSの9タブレットに電話や事前のiOS 9デバイス上の古いinputAccessoryViewメソッドを使用して、より新しいinputAssistantItemてることに注意してください:inputAssistantItemとinputAccessoryViewがARCで動作しなくなりました

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では、ボタンの1つをタップするとクラッシュする([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セレクタを無効なメソッドに変更すると、...

...何も起こりません。これは、ボタンセレクタが呼び出されるまでにtextInputToolbarが何も表示されないことを示しています。これは、nilでなければ認識できないセレクタクラッシュが発生するためです。

しかし、viewDidLoadのログインが発生し、ビューがinputAccessoryViewの電話機とiOS 8タブレットとして表示されるため、TextInputToolbarクラスとそのビューが読み込まれていることがわかりました。

何が起こっているのか、またトラブルシューティングには他に何ができるのですか?

答えて

1

あなたのコードは決して正確ではなく、漏れのためにしか機能しませんでした。あなたは基本的にビューコントローラを失っている/保持していません。以前は存在し続けていましたが、ARCの下ではリリースされているので、ボタンに反応するものは何もありません。 ARCはあなたの記憶上の問題を修正し、問題があることをあなたに知らせましたが、それは考え方ではありません。

修正するには、ビューの使用中にView Controllerを保持します。

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

しかし、あなたはいけない:

また、あなたがすることを学んだところ私はわかりません。そのすべてを1行で行います。 initから返されたオブジェクトを無視しないでください。最初に呼び出したオブジェクトとは異なる場合があります。これらのコードを呼び出すときに何が起こったのかあり

+0

あなたが正しいです、私はちょうど私が非ARCの機能を壊して確認textInputToolbarにautoreleaseを持っている必要があります。この状況でtextInputToolbarを正しく保持して解放する方法を教えてください。ローカル変数の代わりに親ビューコントローラのインスタンス変数を使用する必要がありますか、またはこのコードブロック内のすべてをどうにかして行うことはできますか? – arlomedia

+0

インスタンス変数である包含ビューコントローラにプロパティを追加する必要があります。 – Wain

+0

ありがとう、それはそれを解決しました。 – arlomedia

1

:iOSの8で

UITextView *textInputMultiline = [[UITextView alloc] initWithFrame:frame]; 

//alloc textInputToolbar (textInputToolbar.retaincount = 1) 
TextInputToolbar *textInputToolbar = [TextInputToolbar alloc]; 
textInputToolbar.textView = textInputMultiline; 

if ((self.appDelegate.isTablet)&&([[[UIDevice currentDevice] systemVersion] compare:@"9.0"] != NSOrderedAscending)) { 
    NSMutableArray *barButtonItems = [NSMutableArray array]; 
    //add button items.... 
    UIBarButtonItem *representativeItem = nil; 

    //alloc UIBarButtonItemGroup (group.retaincount = 1) 
    UIBarButtonItemGroup *group = [[UIBarButtonItemGroup alloc] initWithBarButtonItems:barButtonItems representativeItem:representativeItem]; 

    //strong reference group (group.retaincount = 2) 
    textInputMultiline.inputAssistantItem.trailingBarButtonGroups = [NSArray arrayWithObject:group]; 
    //autorelease group 

} else { 
    //strong reference textInputToolbar.view (textInputToolbar.view.retaincount = 2) 
    textInputMultiline.inputAccessoryView = textInputToolbar.view; 
} 

//autorelease textInputToolbar (textInputToolbar.retaincount = 0, textInputToolbar.view.retaincount = 1) 

、textInputToolbarはにdeallocになりますが、それはビューではないでしょうです。そのため、ボタンを見ることができますが、クリックするとオブザーバがワイルドポインタとなり、実行時に関数が見つからずクラッシュしました。

iOS 9では、textInputToolbarもdeallocになります。ボタンアイテムを作成し、InputToolbarからオブザーバー(weak reference)ターゲットを設定するので、textInputToolbar deallocが実行されると、オブザーバはnilになります。この関数は呼び出されません。

関連する問題