Swift 3:有什么办法可以声明一个静态类函数来将闭包类型限制为Self?

时间:2017-03-08 00:30:06

标签: swift generics

我正在尝试在泛型类上创建一个静态方法,该方法接受一个闭包作为参数并创建一个类的实例并将其传递给闭包。问题是我希望将其子类化,并确保闭包符合我使用的任何子类。

我知道你可以使用“Self”作为静态方法的返回类型,但是当我尝试在方法头中使用它时,我收到以下错误:

  

“'Self'仅在协议中或作为方法的结果   在课堂上“

我想做这样的事情:

class GenericClass: NSObject {
    required override init() {
        super.init()
    }

    static func createAndExecuteAsync(block: (Self) -> Void) {
        DispatchQueue.global().async {
            let instance = self.init()
            block(instance)
        }
    }
}

class OtherClass: GenericClass {
    // ...
}

其他地方......

OtherClass.createAndExecuteAsync { (instance: OtherClass) in
    // Do stuff to instance
}

更新:

感谢Hamish在this post的解决方案,我更接近解决方案。如果我首先为我的泛型类创建一个协议,我可以以所需的方式使用Self。然而,这迫使我做出最终的OtherClass,这对我的情况来说是不可取的。

在没有使OtherClass最终的情况下,我收到以下错误:

  

协议'GenericClass'要求'createAndExecuteAsync(block :)'   不能被非最终类('OtherClass')所满足,因为它   在非参数非结果类型位置使用“Self”。

这就是它的样子:

protocol GenericClass {
    init()
    static func createAndExecuteAsync(block: @escaping (Self) -> Void)
}

extension GenericClass {
    static func createAndExecuteAsync(block: @escaping (Self) -> Void) {
        DispatchQueue.global().async {
            let instance = self.init()
            block(instance)
        }
    }
}

final class OtherClass : GenericClass {
    var myProperty = 1

    required init() { }
}

// Somewhere else...
OtherClass.createAndExecuteAsync { (instance) in
    instance.myProperty = 2
}

1 个答案:

答案 0 :(得分:0)

也许您可以使用具有略微不同的使用语法的全局泛型函数。

例如:

 func createAndExecuteAsync<T:GenericClass>(_ objectType:T.Type, _ block:@escaping (T) -> Void)
 {
     DispatchQueue.global().async 
     {
         let instance = T.init()
         block(instance)
     }
 }


 createAndExecuteAsync(OtherClass.self){ $0.myProperty = 2 }

 // instead of OtherClass.createAndExecuteAsync{ $0.myProperty = 2  }