0
私は1つの引数(someArg)を取るinitメソッドを呼び出すためにswiftクラス(someClass)でリフレクションを適用しようとしていますが、1つの引数を持つinitセレクタとIMPを取得できました。私は引数を持たないinitを呼び出すことに終わるIMPを呼び出します。下のプレイグラウンドでは、私はいつも「間違ったinitと呼ばれる」を印刷します。 私はオーバーライドINITを削除した場合、私は次のエラーを取得する:Swiftでパラメータ化された初期化子のリフレクション
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()