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

Swift 3:有没有办法声明一个静态类函数来限制闭包类型为Self?,swift,generics,Swift,Generics,我试图在一个泛型类上创建一个静态方法,它接受一个闭包作为参数,创建一个类的实例,并将闭包传递给它。关键是我想将其子类化,并确保闭包符合我使用的任何子类 我知道您可以使用“Self”作为静态方法的返回类型,但当我尝试在方法头中使用它时,会出现以下错误: “'Self'仅在协议中或作为方法的结果可用 在课堂上” 我想这样做: class GenericClass: NSObject { required override init() { super.init() }

我试图在一个泛型类上创建一个静态方法,它接受一个闭包作为参数,创建一个类的实例,并将闭包传递给它。关键是我想将其子类化,并确保闭包符合我使用的任何子类

我知道您可以使用“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
}
更新:

多亏了哈米什在中的解决方案,我更接近于一个解决方案。如果我首先为我的泛型类创建一个协议,那么我就可以以期望的方式使用Self。然而,这迫使我让另一门课进入决赛,这对我的情况来说是不可取的

如果不将OtherClass设置为final,则会出现以下错误:

协议“GenericClass”要求“createAndExecuteAsync(块:)” 无法由非最终类(“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
}

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

例如:

 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  }
func createAndExecuteAsync(\uobjecttype:T.Type,\ublock:@escaping(T)->Void)
{
DispatchQueue.global().async
{
让instance=T.init()
块(实例)
}
}
createAndExecuteAsync(OtherClass.self){$0.myProperty=2}
//而不是OtherClass.createAndExecuteAsync{$0.myProperty=2}

强相关(重复?):。如中所示,您可以使用协议并将
createAndExecuteAsync
方法放入该协议的扩展中。但归根结底,没有真正的理由说明在协议扩展之外不可能做到这一点。@Hamish感谢您在那篇文章中为我指出了您的解决方案。这迫使我使用最后一个类,这并不理想,但它使我更接近于一个解决方案。啊,是的,这是我在回答中提到的一个粗糙的边缘-你必须从协议要求中删除
createAndExecuteAsync
,只在扩展中保留它。这应该允许您的代码使用非最终类进行编译:)