Mar*_*eIV 3 reflection mirror swift
在Swift 4中,是否有可能在当前模块中找到符合特定协议的所有类型?
例如,假设我已经定义了此协议和以下类:
protocol Animal{}
protocol Vehicle{}
protocol Favorite{}
class Dog : Animal{
}
class Cat : Animal, Favorite{
}
class Car : Vehicle{
}
class Bicycle : Vehicle, Favorite{
}
Run Code Online (Sandbox Code Playgroud)
我想找到所有实现的类型Favorite
。这可以在C#中轻松完成,但是我不确定是否可以在Swift中进行。
如果有帮助,我正在使用Swift 4。
我不认为Swift目前有一个“本机”(不依赖于Objective-C运行时)API来进行这种反射。
但是,如果您使用的是Apple平台(因此具有Obj-C互操作性),则可以获取在Obj-C运行时注册的所有类的列表,然后过滤符合给定协议的类。这将适用于Swift类(甚至是那些不继承自的类NSObject
),因为在底层,Swift类是建立在Obj-C类之上的(当有Obj-C互操作时)。
因为这仅适用于类(不适用于结构或枚举),所以您可能希望限制协议,以便只有类才能符合它:
protocol Favorite : class {}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用进行以下操作objc_copyClassList
:
import Foundation
protocol Animal {}
protocol Vehicle {}
protocol Favorite : class {}
class Dog : Animal {}
class Cat : Animal, Favorite {}
class Car : Vehicle {}
class Bicycle : Vehicle, Favorite {}
/// Invokes a given closure with a buffer containing all metaclasses known to the Obj-C
/// runtime. The buffer is only valid for the duration of the closure call.
func withAllClasses<R>(
_ body: (UnsafeBufferPointer<AnyClass>) throws -> R
) rethrows -> R {
var count: UInt32 = 0
let classListPtr = objc_copyClassList(&count)
defer {
free(UnsafeMutableRawPointer(classListPtr))
}
let classListBuffer = UnsafeBufferPointer(
start: classListPtr, count: Int(count)
)
return try body(classListBuffer)
}
// .flatMap in Swift < 4.1
let classes = withAllClasses { $0.compactMap { $0 as? Favorite.Type } }
print(classes) // [Bicycle, Cat]
Run Code Online (Sandbox Code Playgroud)
在此,我们呼吁compactMap(_:)
在UnsafeBufferPointer
找回代表类型符合元类型的数组Favorite
(即那些可以强制转换为生存元类型Favorite.Type
)。
归档时间: |
|
查看次数: |
510 次 |
最近记录: |