2016-07-09 1 views
0

이 코드를 사용하여 iOS 앱의 화면 키보드 위에 버튼을 추가하고 있습니다. 내가 전화와 사전 아이폰 OS 9 장치에 이전 inputAccessoryView 방법 및 iOS 9 태블릿 새로운 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에 autoreleases를 가지고 있었고 initWithNibName 전에 (void) 캐스트를 가지지 않았다.) 이제 버튼은 여전히 ​​예상대로 나타나지만 그렇지 않다. 작업. iOS 8에서는 버튼 중 하나 (, 유효하지 않은 메모리 포인터를 나타냄)를 탭하면 충돌이 발생하며 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는 메모리 문제를 해결하여 문제가 있음을 알고 있습니다 (생각은별로 아니지만).

수정하려면보기를 사용하는 동안보기 컨트롤러를 유지하십시오.

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

하지만 당신은 안 :

또한, 당신이 배운 어디 모르겠어요. 그 모든 것을 한 줄로하십시오. init 호출에서 반환 된 객체를 무시하지 마십시오. 원래 호출 한 객체와 다를 수 있습니다.

+0

맞습니다. textInputToolbar에 autorelease가 있어야하는데, 방금 확인한 비 ARC 기능이 중단되었습니다. 이 상황에서 textInputToolbar를 올바르게 유지하고 해제하는 방법을 보여줄 수 있습니까? 로컬 변수 대신 상위 뷰 컨트롤러의 인스턴스 변수를 사용해야합니까, 아니면이 코드 블록 내에서 모든 것을 어떻게 든 할 수 있습니까? – arlomedia

+0

포함 된 뷰 컨트롤러에 인스턴스 변수 인 yes를 추가해야합니다. – Wain

+0

고마워, 그게 해결 됐어. – arlomedia

1

는이 코드를 호출 할 때 무슨 일이 있었는지 있습니다 :

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) 

아이폰 OS 8에서 textInputToolbar이 할당 해제 될 것입니다하지만보기는하지 않습니다이다. 그래서 버튼을 볼 수 있지만 클릭하면 관찰자가 와일드 포인터가되어 런타임이 함수를 찾을 수 없어 추락했습니다.

iOS 9에서 textInputToolbar도 dealloc입니다. 단추 항목을 만들고 InputToolbar에서 관찰 (약한 참조) 대상을 설정했기 때문에 textInputToolbar가 할당 해제되면 관찰이 nil이되었습니다. 따라서 함수가 호출되지 않습니다.