Swift

2016-04-08 21 views
0

parametreli Initializer Yansıma Bir argüman (bazıArg) alır bir init yöntemini çağırmak için hızlı bir sınıf (someClass) yansıma uygulamak için çalışıyorum, 1 bağımsız değişkeni olan init seçici ve IMP almayı başardı, ancak IMP'yi çağırıyorum, init'i hiçbir argüman olmadan çağırıyor. Aşağıdaki Oyun alanında her zaman "yanlış init" olarak adlandırılır. Ben aşağıdaki hatayı alıyorum geçersiz kılma init kaldırırsanız:Swift

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

ben eksik?

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() 

cevap

0

olmayan parametrized init varsayılan olarak iki argüman vardır çıkıyor ve parametreli init methodName olarak "initWithNum" olurdu.

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

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

     } 
}