当前位置:首页 > 操作系统 > Ios

IOS 错误 [UIWebView cut:]: unrecognized selector sent to instance

那在什么场景中会出现这种情况呢?

如果一个包含文字的输入元素有焦点,然后按钮的点击会导致输入失去焦点,然后接下来在输入时双按会重新得到焦点并从弹出bar中选择剪切复制粘贴,就会导致此error。

也就是说当WebView页面中的HTML中有如下代码的时候

            <
            input 
            type
            ="text"
            >
            <
            input 
            type
            ="button"
            >
        

即有输入框和按钮的时候,会出现 [UIWebView cut:]: unrecognized selector sent to instance 的错误风险

简单的说就是若有一个WebView中有输入框,又有按钮的话,执行下面的操作就会出现这样的错误:

1.在输入框中输入内容。

2.点击Button让键盘消失。

3。双击输入框中的内容出现选择的bar后点击剪贴。就会出现闪退的现象。

的具体错误如下:

            2015-11-2011:20:59.495 WebViewCutErrorDemo[3381:595295] -[UIWebView cut:]: unrecognized selector sent to instance 0x7f9612f19f402015-11-2011:20:59.497 WebViewCutErrorDemo[3381:595295] *** Terminating app due to uncaught exception NSInvalidArgumentException, reason: -[UIWebView cut:]: unrecognized selector sent to instance 0x7f9612f19f40
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010ddb6f45 __exceptionPreprocess + 1651   libobjc.A.dylib                     0x000000010d82edeb objc_exception_throw + 482   CoreFoundation                      0x000000010ddbf56d -[NSObject(NSObject) doesNotRecognizeSelector:] + 2053   CoreFoundation                      0x000000010dd0ceea ___forwarding___ + 9704   CoreFoundation                      0x000000010dd0ca98 _CF_forwarding_prep_0 + 1205   UIKit                               0x000000010e6a3923 -[UICalloutBar buttonPressed:] + 4146   UIKit                               0x000000010e6a1e47 -[UICalloutBarButton fadeAndSendAction] + 817   Foundation                          0x000000010d416c39 __NSFireDelayedPerform + 4028   CoreFoundation                      0x000000010dd17264 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 209   CoreFoundation                      0x000000010dd16e11 __CFRunLoopDoTimer + 108910  CoreFoundation                      0x000000010dcd8821 __CFRunLoopRun + 193711  CoreFoundation                      0x000000010dcd7e08 CFRunLoopRunSpecific + 48812  GraphicsServices                    0x000000011158fad2 GSEventRunModal + 16113  UIKit                               0x000000010e16430d UIApplicationMain + 17114  WebViewCutErrorDemo                 0x000000010d32c86f main + 11115  libdyld.dylib                       0x00000001104f292d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

仔细想想第三方登录的页面有出现这种问题的风险。

有人说这里面说是苹果系统的bug,原因是这种操作在响应链不能正确的发送,并最终发送到UIWebView的实例,而不是内部的UIWebDocumentView。

下面提供一下这种问题的解决方案,思想就是动态的为UIWebView添加响应的方法。

新建一个类 CutCopyPasteFixedWebView 继承 UIWebView

CutCopyPasteFixedWebView.h代码如下

            //
            //
              CutCopyPasteFixedWebView.h

            //
              WebViewCutErrorDemo

            //
            //
              Created by lidaojian on 15/11/20.

            //
              Copyright ? 2015年 lidaojian. All rights reserved.

            //

            #import <UIKit/UIKit.h>

@interface CutCopyPasteFixedWebView : UIWebView


@end

CutCopyPasteFixedWebView.m代码如下

            //
            //
              CutCopyPasteFixedWebView.m

            //
              WebViewCutErrorDemo

            //
            //
              Created by lidaojian on 15/11/20.

            //
              Copyright ? 2015年 lidaojian. All rights reserved.

            //

            #import
            "
            CutCopyPasteFixedWebView.h
            "
            #import <objc/runtime.h>

@implementation CutCopyPasteFixedWebView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        /// 适配防止崩溃        [self prepareForNoCrashes];
    }
    return self;
}

- (UIView *)internalView
{
    staticconstchar internalViewKey = ;
    /// 动态关联
    UIView *internalView = objc_getAssociatedObject(self, &internalViewKey);
    if (internalView == nil && self.subviews.count > 0) {
        for (UIView *view in self.scrollView.subviews) {
            if ([[view.class description] hasPrefix:@"UIWeb"]) {
                internalView = view;
                objc_setAssociatedObject(self, &internalView, view, OBJC_ASSOCIATION_ASSIGN);
                break;
            }
        }
    }
    return internalView;
}

void webViewImplementUIResponderStandardEditActions(id self, SEL selector, id param)
{
    /// IMP本质就是函数指针 methodForSelector 获得一个指向方法实现的指针,并可以使用该指针直接调用方法实现
    IMP imp = [[self internalView] methodForSelector:selector];
    
    /// 函数指针void (*method)(id, SEL, id) = (void (*) (id, SEL, id))imp;
    
    /// 直接用函数指针调用方法    method([self internalView], selector, param);
    
}

- (void)prepareForNoCrashes
{
    NSArray *selectors = @[@"cut:", @"copy:", @"paste:", @"select:", @"selectAll:", @"delete:", @"makeTextWritingDirectionLeftToRight:", @"makeTextWritingDirectionRightToLeft:", @"toggleBoldface:", @"toggleItalics:", @"toggleUnderline:", @"increaseSize:", @"decreaseSize:"];

    for (NSString *selName in selectors) {
        
        /// 动态的根据方法名来获取方法
        SEL selector = NSSelectorFromString(selName);
        
        /// 若父类没有实现则给父类添加selector方法,若父类实现了,并不修改父类的selector方法
        class_addMethod(self.class, selector, (IMP)webViewImplementUIResponderStandardEditActions, "");
    }
}

@end

另外附上测试的HTML文件

            <
            html
            >
            <
            head
            >
            </
            head
            >
            <
            body
            >
            <
            br
            ><
            br
            >
            <
            input 
            type
            ="text"
            >
            <
            input 
            type
            ="button"
            >
            </
            body
</html
            >
        

若有疑问请加本人QQ:610774281。一起探讨一起进步。。。。 

参考连接:

http://stackoverflow.com/questions/21316784/uiwebview-bug-uiwebview-cut-unrecognized-selector-sent-to-instance#

 

原文:http://www.cnblogs.com/lidaojian/p/4980269.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!