Рекурсивное воспаление приводит к аварии

Я использую DAKeyboardControll в моем приложении. у него есть метод с именем: swizzled_addSubview и реализовать как это:

- (void)swizzled_addSubview:(UIView *)subview
 {

if (!subview.inputAccessoryView)
{
    if ([subview isKindOfClass:[UITextField class]])
    {
        UITextField *textField = (UITextField *)subview;
        if ([textField respondsToSelector:@selector(setInputAccessoryView:)])
        {
            UIView *nullView = [[UIView alloc] initWithFrame:CGRectZero];
            nullView.backgroundColor = [UIColor clearColor];
            textField.inputAccessoryView = nullView;
        }
    }
    else if ([subview isKindOfClass:[UITextView class]]) {
        UITextView *textView = (UITextView *)subview;
        if ([textView respondsToSelector:@selector(setInputAccessoryView:)] && [textView respondsToSelector:@selector(isEditable)] && textView.isEditable)
        {
            UIView *nullView = [[UIView alloc] initWithFrame:CGRectZero];
            nullView.backgroundColor = [UIColor clearColor];
            textView.inputAccessoryView = nullView;
        }
    }
}
[self swizzled_addSubview:subview];  

}

проблема

Недавно в моей новой версии, совместимой с AutoLayout, я получил некоторые сбои в этом методе и причины их:-[UIView(DAKeyboardControl) swizzled_addSubview:],EXC_BAD_ACCESS KERN_PROTECTION_FAILURE at 0x0090dffc

Я знаю, что эта проблема произошла для многих, но почему она не может работать правильно?

этот сбой произошел только для 8 пользователей 54 раза, у 50 % из них устройство для джейлбрейка, а у другого - устройство без джейлбрейка!

2 ответа

Метод Swizzling вызывает проблемы во время выполнения. Я также получил такое же исключение, чтобы избавиться от этого, я использовал BABFrameObservingInputAccessoryView, который отлично работает для меня. https://github.com/brynbodayle/BABFrameObservingInputAccessoryView

Скорее всего, ваш метод на самом деле не работает, поэтому вы получите рекурсивный вызов, который, очевидно, завершится сбоем. Это хитрая вещь в Swizzling: он обменивается двумя методами, поэтому каждый вызов addSubview будет вызывать swizzled_addSubview, а вызов swizzled_addSubview фактически вызывает addSubview.

Другие вопросы по тегам