美文网首页
Swift3.0中unrecognized selector

Swift3.0中unrecognized selector

作者: 雪雪雪雪佳佳佳佳 | 来源:发表于2017-02-16 17:02 被阅读129次

    写的有点乱

    // 为了好测试 只对UIResponder做了延展 讲道理应该给NSobject 做延展

    extension UIResponder {

                 // 消息转发

                   open override func forwardingTarget(for aSelector: Selector!) -> Any? {

                // selectorStr 为方法名字

               let selectorStr: String = NSStringFromSelector(aSelector)

              // 只检测 UIResponder 的子类 其余暂不检测

              if self.isKind(of: NSClassFromString("UIResponder")!) {

               // 创建一个虚拟类 RXSwiftTestNew  为项目名字  MyClass 为类名字

                     let newClass = objc_allocateClassPair(NSObject.classForCoder(),    "RXSwiftTestNew.MyClass", 0)

                    // 为 newClass 添加 ; 一个方法 名字 为 selectorStr  ;实现方式为 dosome 所对应的imp指针; v 代表无返回值 ,由于没写 @: 说明无参。这里有个坑,如果用默认的 会默认两个参数。

                    class_addMethod(newClass, aSelector,dosome(aSelector: aSelector), UnsafeMutablePointer(mutating: "v"))

              //注册这个类

               objc_registerClassPair(newClass)

               // 返回 newClass 的实例  让这个方法的实现转发到 newClass

                let Protector: AnyClass? = newClass.self

                 let instance: Any? = Protector

    // 下面是做个测试 获取新建虚拟类的方法列表

                 var methodCount:UInt32 = 0

              let methodList = class_copyMethodList(Protector.self, &methodCount)

            for i in 0..

              let temp = methodList?[Int(i)]

                 var imp = method_getImplementation(temp)

              var name_f = method_getName(temp)

             let name_s = sel_getName(method_getName(temp))

                var arguments = method_getNumberOfArguments(temp)

                let encoding = method_getTypeEncoding(temp)

                print("方法名:\(NSString(utf8String: name_s!)),参数个数:\(arguments),编码方式\(NSString(utf8String: encoding!)))")

    }

                 // 实验结束

             // 比较惆怅的是  方法已经添加上了 但是无法响应

                 return instance!

           }else{

                  return nil

          }

    }

    func dosome(aSelector:Selector)->IMP?{

                let block = {()->() in

               // 预计 闪退就会走这里

                   print("没有闪退" + NSStringFromSelector(aSelector)) 

                   }

                  // 这里也是个坑 这种操作是不安全的  所以Swift 要求我们必须这么包装一层 否则若直接使用block无法编译!!!!

                 let castedBlock: AnyObject = unsafeBitCast(block as @convention(block) () -> Void, to: AnyObject.self)

               let swizzledImplementation = imp_implementationWithBlock(castedBlock)

             // 返回 block 对应的方法指针

              return swizzledImplementation

               }

     }

    ps: 为什么我已经在类用class_addMethod添加了这个方法,但是却无法用performSelector调用呢? 求大神解答

    感谢 @Mad_Mark  @网易大白

    相关文章

      网友评论

          本文标题:Swift3.0中unrecognized selector

          本文链接:https://www.haomeiwen.com/subject/cwjhwttx.html