在swift中调用具有动态类名的方法

Vkh*_*arb 5 ios swift swift4.1

如何用动态类名调用类函数?

假设以下示例中我有两个类具有相同签名的方法

class Foo{
   class func doSomething()

}

class Foobar {
   class func doSomething()
}

class ActualWork{
   //call following method with a variable type so that it accepts dynamic class  name
   func callDynamicClassMethod(x: dynamicClass)
    x.doSomething() 
  }
Run Code Online (Sandbox Code Playgroud)

如何实现这一点,以便x在运行时接受值

编辑:对不起,我错过了提到我正在寻找除协议导向方法以外的任何其他方式.如果有更直接的方法/ pods /库来实现这一目标,这就是一个探索性的问题.

SIl*_*ter 7

泛型和面向协议的编程将完成这项工作:

protocol Doable {

    static func doSomething()
}

class Foo: Doable {

    static func doSomething() {
        debugPrint("Foo")
    }
}

class Foobar: Doable {

    static func doSomething() {
        debugPrint("Foobar")
    }
}

class ActualWork {

    func callDynamicClassMethod<T: Doable>(x: T.Type) {
        x.doSomething()
    }
}

let work = ActualWork()

work.callDynamicClassMethod(x: Foo.self)
work.callDynamicClassMethod(x: Foobar.self)
Run Code Online (Sandbox Code Playgroud)


Nik*_*tin 6

我喜欢这个问题,因为它让我想到了一个开箱即用的点缀.

我将通过将其分成几个部分来回答它.

第一

调用类函数

类函数基本上是一种Type方法,可以使用上下文中的static单词来实现class.

考虑到这一点,你可以得到一个简单的解决方案,使用协议并传递类引用(符合该协议),如下所示:

protocol Aaa{
   static func doSomething();
}
class Foo : Aaa{
  static func doSomething() {
    print("Foo doing something");
  }
}
class FooBar : Aaa{
  static func doSomething() {
    print("FooBar doing something");
  }
}

class ActualWork{

  //Using class (static) method
  func callDynamicClassMethod <T: Aaa> (x: T.Type) {
    x.doSomething();
  }
}


//This is how you can use it
func usage(){
    let aw = ActualWork();

    aw.callDynamicClassMethod(x: Foo.self);
    aw.callDynamicClassMethod(x: Foo.self);
}
Run Code Online (Sandbox Code Playgroud)

第二

如果你真的不需要类上下文的方法,你可以考虑使用实例方法.在这种情况下,解决方案会更简单,如下所示:

protocol Bbb{
  func doSomething();
}
class Bar : Bbb{
  func doSomething() {
    print("Bar instance doing something");
  }
}
class BarBar : Bbb{
  func doSomething() {
    print("BarBar instance doing something");
  }
}
class ActualWork{
  //Using instance (non-static) method
  func callDynamicInstanceMethod <T: Bbb> (x: T){
    x.doSomething();
  }
}
//This is how you can use it
func usage(){
   let aw = ActualWork();
    aw.callDynamicInstanceMethod(x: Bar());
    aw.callDynamicInstanceMethod(x: BarBar());
}
Run Code Online (Sandbox Code Playgroud)

第三

如果你需要使用class func语法,就像OP最初做的那样:

class func doSomething()

你不能简单地使用协议.因为协议不是类...所以编译器不允许它.

无法在协议内声明类函数

但是仍然可以通过使用SelectorNSObject.perform方法实现这一点

像这样:

class ActualWork : NSObject{

    func callDynamicClassMethod<T: NSObject>(x: T.Type, methodName: String){
        x.perform(Selector(methodName));
    }

}

class Ccc : NSObject{
    @objc class func doSomething(){
        print("Ccc class Doing something ");
    }

}

class Ddd : NSObject{
    @objc class func doSomething(){
        print("Ccc class Doing something ");
    }

    @objc class func doOther(){
        print("Ccc class Doing something ");
    }
}

//This is how you can use it
func usage() {
    let aw = ActualWork();

    aw.callDynamicClassMethod(x: Ccc.self, methodName: "doSomething");
    aw.callDynamicClassMethod(x: Ddd.self, methodName: "doSomething");
    aw.callDynamicClassMethod(x: Ddd.self, methodName: "doOther");

}
Run Code Online (Sandbox Code Playgroud)