Check if class conforms to protocol

前端 未结 3 1953
無奈伤痛
無奈伤痛 2020-12-18 02:10

I am trying to make a simple Dependency Injection system for our app in swift, for 2 day now. I\'m flexible to whatever solution but I would like something so I can say \"gi

相关标签:
3条回答
  • 2020-12-18 02:40

    The comment given by nhgrif is the correct answer for Swift 2. You should use an optional binding:

    if let aObjectWithAProtocol = aObject as? AProtocol {
        // object conforms to protocol
        someObject.someFunction(aObjectWithAProtocol)
    } else {
        // object does not conform to protocol
    }
    

    This if let something = obj as? type statement is called optional binding and checks if the object can be type-casted to the given type/class/protocol/....

    If so, you can use the optional (as?) or force unwrap (as!) the object.

    0 讨论(0)
  • 2020-12-18 02:47

    This function will perfectly meet your requirement:

    bool _swift_typeIsTargetType(id sourceType, id targetType)

    It can check whether a swift type is the target type (is same type or subclass, or conforms to the target protocol), works like is operator in swift. But it's for a type, not for an instance:

    let sourceType: Any.Type = type(of: self)
    let targetType: Any.Type = AnyProtocol.self
    let result = _swift_typeIsTargetType(sourceType, targetType)
    

    It uses private APIs in libswiftCore.dylib, See swift source code Casting.cpp:

    bool _conformsToProtocols(const OpaqueValue *value, const Metadata *type, const ExistentialTypeMetadata *existentialType, const WitnessTable **conformances)
    

    Optional binding is not same. It can also check conformance, but you can't dynamically give the type to check:

    let targetType: Any.Type = AnyProtocol.self
    //error: use of undeclared type: 'targetType'
    if let _ = aObject as? targetType {
        // object conforms to protocol
    } else {
        // object does not conform to protocol
    }
    

    This function is used in ZIKRouter. It's a module router and also a Dependency Injection framework. It uses protocol to discover modules and inject dependencies. You can try it if you want to do something like 'finding a module conforming to some protocol'.

    0 讨论(0)
  • 2020-12-18 03:04

    If you import obj-c then you can do something like you used to.

    Otherwise, it's hard because protocols don't exist in the same way. Consider a registration based system for your factory. Each of your classes would register themselves by supplying a function or closure that can be called to return a new instance of that class, and the registration is against a string or some other type of identifier. This is where it would be good to have a protocol type, but in obj-c you were really doing the same thing with a string conversion. You could register against anything that is Equatable to keep things very generic.

    0 讨论(0)
提交回复
热议问题