ios - Typhoon - 如何注入(inject)符合 PROTOCOL 而不是 CLASS 的参数

标签 ios swift dependency-injection typhoon

我有代表登录用户的类

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

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

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?'

最佳答案

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

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

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

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

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

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

关于ios - Typhoon - 如何注入(inject)符合 PROTOCOL 而不是 CLASS 的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27191058/

相关文章:

unit-testing - 我可以在 Visual Studio 单元测试(类库)项目中使用 Xamarin.Forms.DependencyService 吗?

iphone - 获取google plus用户好友

ios - 使用 AVAssetWriter 重新编码 H264 mov 文件 - 如何设置帧率?

android - NodeJS + SocketIO 推送到移动应用

ios - UIActivityViewController swift !在 iPad 上崩溃

macos - 在 Swift 中使用 NSInputStream 从 STDIN 获取输入

JavaScript 设计模式 : Injecting a dependency that is not yet created

java - Apache Camel 与构造函数注入(inject)

ios - 提交到应用商店时可以设置多低的部署目标是否有限制?

arrays - 如何将动态数据快速获取到数组 KingFisher