2

我有代表登录用户的类

public class User: NSObject {        
    init(authenticator: Authenticator) {        
        self.authenticator = authenticator
    }
    ... 
}

它唯一的初始参数是符合Authenticator 协议的对象

protocol Authenticator
{
    func authenticate(login:String , password:String , handler: (result:AuthenticationResult)->()  )
}

在我的例子中,Auth 对象是类BackendService的实例

我的台风大会定义是:

public dynamic func user() -> AnyObject {
    return TyphoonDefinition.withClass(User.self) {
        (definition) in

        definition.useInitializer("initWithAuthenticator") {
            (initializer) in

            initializer.injectParameterWith( self.backendService() )
        }            
    }
}

应用程序导致运行时错误

'Method 'initWithAuthenticator' has 0 parameters, but 1 was injected. Do you mean 'initWithAuthenticator:'?'

如果我将 init 方法更改为 'initWithAuthenticator:' 它会崩溃

'Method 'initWithAuthenticator:' not found on 'PersonalMessages.User'. Did you include the required ':' characters to signify arguments?'
4

1 回答 1

1

目前,有必要将 '@objc' 指令添加到 Swift 协议中,以使它们可用于 Typhoon 的依赖注入。没有它,objective-c 运行时的内省和动态调度功能不可用,这些都是必需的。

同样,对于一个类,它必须从 NSObject 扩展或具有“@objc”指令,否则它还将使用 C++ 样式的 vtable 调度并且(基本上)没有反射。对于私有变量或方法,它们还必须具有“动态”修饰符。

虽然 vtable 调度更快,但它可以防止运行时方法拦截,许多 Cocoa 最强大的特性,如 KVO 所依赖的。所以这两种范式都很重要,而且 Swift 可以在它们之间切换令人印象深刻。但是,在协议的情况下,使用“@objc”指令有点不幸,因为它意味着“遗留”行为。也许“动态”会更好?

dynamic protocol Authenticator //Not supported but would've been a nicer than '@objc'?

或者,暗示需要动态行为的另一种方式可能是让协议扩展 NSObject 协议,但这不起作用。所以使用 '@objc' 是唯一的选择。

同时,就使用 Cocoa/Touch 应用程序而言,对于扩展 NSObject 的类的要求并不明显。

于 2014-11-28T15:50:53.650 回答