我正在尝试构建一个协议类型的"过滤"数组
我有一系列符合几种不同协议的结构(评估,级别和门) - 可分级,可重复和可测试:
protocol Stageable
{
var index : Int { get }
var steps : [Step] { get }
}
protocol Testable
{
var threshold : Float { get }
}
protocol Repeatable
{
var sessions: Int { get }
}
struct Gate : Stageable, Testable, Repeatable
{
private(set) var index : Int
private(set) var steps : [Step]
private(set) var threshold : Float
private(set) var sessions : Int
}
struct Assessment : Stageable, Testable
{
private(set) var index : Int
private(set) var steps : [Step]
private(set) var threshold : Float
}
struct Level : Stageable, Repeatable
{
private(set) var index : Int
private(set) var steps : [Step]
private(set) var sessions : Int
}
Run Code Online (Sandbox Code Playgroud)
Step是另一个结构.没有使用任何类.
这些结构在添加到数组之前就已填充.数组通常采用[Assessment,Gate,Level,Level]的形式.所有结构数据都从XML文件填充.
在某些情况下,我只想查看数组中的"级别",所以我这样做:
// stages = [Assessment, Gate, Level, Level, ...]
let levels = stages.filter{ $0 is Level }
Run Code Online (Sandbox Code Playgroud)
如果我查询它,它看起来很好,例如levels.count是我所期望的.但是,如果我现在想要将数组转换为[Level],则会因以下错误而崩溃:
fatal error: can't unsafeBitCast between types of different sizes
Run Code Online (Sandbox Code Playgroud)
这是因为我从一个协议转换为结构类型?我也觉得我已经错过了协议的主要好处,必须有更好的方法来做到这一点.
目前正在使用Xcode 7 beta 5.
构造结构数组是有问题的,因为结构是值类型.这意味着结构数组的每个元素占用内存中结构的大小.这对于标准对象的数组是不同的,因为它们通过引用传递.对象数组中的每个元素都是一个引用(指向特定内存区域的指针).
为了证明这一点,请考虑以下内容
class ABC {
private var i = 0
private var j = 1
private var k = 2
}
print(sizeof(UIViewController))
print(sizeof(UIImage))
print(sizeof(NSObject))
print(sizeof(ABC))
Run Code Online (Sandbox Code Playgroud)
我的平台上的每个print语句输出8都是内存地址的大小(显然不同于此类实例占用的内存量).
另一方面,当我从您的问题中获取代码并执行此操作时
print(sizeof(Stageable))
print(sizeof(Level))
Run Code Online (Sandbox Code Playgroud)
我得到40和24其分别是在内存中,这些结构的情况下的实际尺寸.这意味着类型数组[Stageable]包含40个字节元素的块,而类型数组[Level]包含24个字节元素的块.因此,您无法在这些数组类型之间进行转换,因为这需要重写数组的内存.
作为替代方法,您可以使用该map方法强制进行类型转换:
let levels = stages.filter({ $0 is Level }).map({ $0 as! Level })
Run Code Online (Sandbox Code Playgroud)
通过利用以下flatMap方法也可以简化上述内容:
let levels = stages.flatMap({ $0 as? Level })
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
485 次 |
| 最近记录: |