swift - Swift 中的参数化初始化器反射

标签 swift reflection

我试图在一个 swift 类 (someClass) 上应用反射来调用一个带有一个参数 (someArg) 的 init 方法,我设法获得了具有 1 个参数的 init 选择器和 IMP,但是当我调用 IMP 时,它最终调用 init 时不带任何参数。在下面的 Playground 中,我总是会打印出“called the bad init”。 如果我删除覆盖 init,我会收到以下错误:

fatal error: use of unimplemented initializer 'init()' for class '__lldb_expr_15.someClass'

我错过了什么?

import UIKit

public class someClass:NSObject{
    init( num:someArg){
        print("called the right init")
    }

    override init(){
        print("called the wrong init")
    }
}

public class someArg:NSObject{
    override init(){

    }
}


public class Test{

    func reflect(){

        let classType: NSObject.Type = someClass.self as NSObject.Type
        let  (initializerWithOneArgImp,selector)  = getInitializerWithArguments(classType, argumentsCount: 1)

        typealias initializerWithOneArgImpType =  @convention(c) (AnyObject, Selector, AnyObject) -> (AnyObject)

        let callback = unsafeBitCast(initializerWithOneArgImp , initializerWithOneArgImpType.self)
        callback(classType,selector,someArg())
    }

    func getInitializerWithArguments(classType:AnyClass, argumentsCount:Int)->(IMP,Selector){

        var methodCount:CUnsignedInt = 0
        let methodList = class_copyMethodList(classType.self, &methodCount)
        let n : Int = Int(methodCount)

        for var i: Int = 0; i < n; i++ {

            let methodSelector = method_getName(methodList[i])
            let methodName:String = String(_sel:methodSelector)

            if(methodName == "init")
            {
                let methodArgumentsCount = method_getNumberOfArguments(methodList[i])

                if(methodArgumentsCount  == UInt32(argumentsCount) + 1)
                {
                    return (method_getImplementation(methodList[i]),methodSelector)

                }
            }
        }
        return (nil,nil)
    }
}
var test = Test()
test.reflect()

最佳答案

事实证明,非参数化 init 默认有两个参数,而参数化 init 将使用“initWithNum”作为 methodName。

if(methodName.hasPrefix("init"))
{
     let methodArgumentsCount = method_getNumberOfArguments(methodList[i])

     if(methodArgumentsCount  == UInt32(argumentsCount) + 2)
     {
            return (method_getImplementation(methodList[i]),methodSelector)

      }
 }

关于swift - Swift 中的参数化初始化器反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36506966/

相关文章:

swift - 适用于 ios 的 google placepicker 和 BackgroundMapViewController.swift

c# - 如何为 AppDomain 预加载所有已部署的程序集

c++ - 什么会导致 Phong 镜面反射着色产生色域溢出?

php - 您可以解决 PHP 中超出范围的后期静态绑定(bind)吗?

reflection - golang 通过反射从接口(interface)获取结构

ios - 如何在 Swift 中将时间/日期数组从最旧到最新排序?

swift - AppleTV 聚焦图像边框不缩放

ios - 如何在 Swift 中对两种类型进行协议(protocol)扩展约束

ios - 计时器设置在 iOS 中不起作用

java - Java 反射中找不到类异常