台风-如何注入符合协议而非类的参数。

时间:2023-01-21 12:08:37

I have class which represents logged user

我有一个表示已登录用户的类。

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

Its only initial arguments is object which conforms to Authenticator protocol

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

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

In my case the Auth object is instance of class BackendService

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

My typhoon assembly definition is:

我的台风集结定义是:

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

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

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

Application cause runtime-error

应用程序会导致运行时错误

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

If i change init method to 'initWithAuthenticator:' it crashes with

如果我将init方法更改为“initWithAuthenticator:”,它就会崩溃

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

1 个解决方案

#1


1  

At the present time, it is necessary to add the '@objc' directive to Swift protocols to have them be available for dependency injection with Typhoon. Without it the objective-c runtime's introspection and dynamic dispatch features arent available and these are required.

目前,有必要将“@objc”指令添加到Swift协议中,使它们能够用于台风的依赖注入。没有它,objective-c运行时的内省和动态调度特性就不可用了,这是必需的。

Similarly, in the case of a class it must extend from NSObject or have the '@objc' directive, otherwise it will also use C++ style vtable dispatch and have (essentially) no reflection. In the case of private vars or methods, they must also have the 'dynamic' modifier.

类似地,在类的情况下,它必须从NSObject扩展或具有“@objc”指令,否则它也将使用c++风格的vtable分派,并且(本质上)没有反射。对于私有vars或方法,它们还必须具有“动态”修饰符。

While vtable dispatch is faster, it prevents runtime method interception which many of Cocoa's most powerful features, such as KVO rely on. So both paradigms are important and its impressive that Swift can switch between them. In the case of protocols though, using the '@objc' directive is a little unfortunate as it implies a 'legacy' behavior. Perhaps 'dynamic' would've been better?

虽然vtable dispatch速度更快,但它阻止了许多Cocoa最强大的特性(比如KVO依赖)的运行时方法拦截。因此,这两种范式都很重要,斯威夫特可以在它们之间转换,这让人印象深刻。但在协议的情况下,使用“@objc”指令有点不幸,因为它暗示了“遗留”行为。也许‘动态’会更好?

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

Or perhaps another way to imply that dynamic behavior is required would be to have the protocol extend the NSObject protocol, however this does not work. So using '@objc' is the only choice.

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

Meanwhile, for classes the requirement to extend NSObject isn't really noticible as far as working with Cocoa/Touch apps goes.

与此同时,对于类来说,扩展NSObject的需求并不像使用Cocoa/Touch应用程序那样容易理解。

#1


1  

At the present time, it is necessary to add the '@objc' directive to Swift protocols to have them be available for dependency injection with Typhoon. Without it the objective-c runtime's introspection and dynamic dispatch features arent available and these are required.

目前,有必要将“@objc”指令添加到Swift协议中,使它们能够用于台风的依赖注入。没有它,objective-c运行时的内省和动态调度特性就不可用了,这是必需的。

Similarly, in the case of a class it must extend from NSObject or have the '@objc' directive, otherwise it will also use C++ style vtable dispatch and have (essentially) no reflection. In the case of private vars or methods, they must also have the 'dynamic' modifier.

类似地,在类的情况下,它必须从NSObject扩展或具有“@objc”指令,否则它也将使用c++风格的vtable分派,并且(本质上)没有反射。对于私有vars或方法,它们还必须具有“动态”修饰符。

While vtable dispatch is faster, it prevents runtime method interception which many of Cocoa's most powerful features, such as KVO rely on. So both paradigms are important and its impressive that Swift can switch between them. In the case of protocols though, using the '@objc' directive is a little unfortunate as it implies a 'legacy' behavior. Perhaps 'dynamic' would've been better?

虽然vtable dispatch速度更快,但它阻止了许多Cocoa最强大的特性(比如KVO依赖)的运行时方法拦截。因此,这两种范式都很重要,斯威夫特可以在它们之间转换,这让人印象深刻。但在协议的情况下,使用“@objc”指令有点不幸,因为它暗示了“遗留”行为。也许‘动态’会更好?

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

Or perhaps another way to imply that dynamic behavior is required would be to have the protocol extend the NSObject protocol, however this does not work. So using '@objc' is the only choice.

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

Meanwhile, for classes the requirement to extend NSObject isn't really noticible as far as working with Cocoa/Touch apps goes.

与此同时,对于类来说,扩展NSObject的需求并不像使用Cocoa/Touch应用程序那样容易理解。