func getClassesFor(_ yourprotocol: Protocol) -> [any AnyObject.Type]
参数 (Parameter): 协议 (Protocol)
返回值 (Returns): [any AnyObject.Type]
返回编译到您的应用程序构建中的,所有符合指定协议的类列表。 如果您在应用程序/包中提供一个协议,以及与任何实现该协议的类进行交互的方式,这将非常有用。 例如,您可以开发一种非常棒的分形查看方式,并为任何人提供一个 Fractal 协议来描述他们自己的分形。 无需修改任何代码,其他开发人员可以实现 Fractal 协议,您的代码可以检测到该类,并将其添加到查看的选择列表中。
如果在 Swift 中调用,为了正确识别预期的协议,必须在调用中将 self
添加到协议名称中。 例如,协议 Foo
必须作为 Foo.self
传递。
例如 (e.g.):
let matchingClassTypes = ProtocolMatcher().getClassesFor(Foo.self)
此外,Swift 协议定义必须用 @objc 标记,此函数才能识别该协议。例如 (e.g.):
@objc Foo { }
如果打算对返回值进行操作,则应将结果强制转换为特定类型。 使用上面的例子,这将是:
let matchingClassTypes = ProtocolMatcher().getClassesFor(Foo.self) as! [any Foo.Type]
不幸的是,在 Swift 包中无法围绕此函数添加更友好的 Swift 包装器,因为在撰写本文时,Swift 包不支持混合语言。
请注意,这与 Swift Mirror 方法不同,后者只能返回已实例化的类,而此方法将返回所有符合给定协议的类,无论是否已实例化。
为了实例化返回的类,协议必须要求一个 init 方法。 有关更多详细信息,请参见下面的示例。
假设我们有一个名为 Secrets 的项目,其中包含以下代码:-
import ProtocolMatcher
// Define a protocol to test for
@objc protocol Food { init(); var secret: String {get} }
// and two conforming class definitions:
final class Baah : Food { init() {}; let secret = "applesauce" }
final class HumBug: Food { init() {}; let secret = "ketchup" }
final class FoodMatch {
static func getFoodSecrets() {
let classesConforming = ProtocolMatcher().getClassesFor(Food.self) as! [any Food.Type]
for classType in classesConforming {
let className = "\(classType)"
let classObject = classType.init()
let secret = classObject.secret
print("Found \(className) .. with a secret of \(secret)")
}
}
}
调用 FoodMatch.getFoodSecrets() 将打印
> Found Baah .. with a secret of applesauce
> Found HumBug .. with a secret of ketchup
https://github.com/disc0infern0/ProtocolMatcher 版权所有 2023 Andrew Cowley