2016-04-08 12 views
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() 

答えて

0

は非パラメータ化initは、デフォルトでは2つの引数を持っていて、パラメータ化initはmethodNameのように「initWithNum」を持っているだろう、判明します。

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

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

     } 
} 
関連する問題