Swift3.0中unrecognized selector

2017-02-16  本文已影响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  @网易大白

上一篇下一篇

猜你喜欢

热点阅读