迅速。是否可以在运行时确定属性时间

时间:2015-09-09 10:14:38

标签: ios swift cocoa design-patterns 3d

我有下一个问题:

我有一个类,它可以包含一些不同类型的数据,但是在编译时不知道数据的类型。

看起来像这样

class Data {
    var dataType: PodDataType = PodDataType.None

    var componentsCount: UInt32 = 0

    var stride: UInt32 = 0

    var data // the data type of this field is unknown until dataType property is initialized
}

我有另一个具有多个数据实例的类,如下所示:

class Mesh {

    var verticesCount: UInt32 = UInt32.max

    var facesCount: UInt32 = UInt32.max

    var UVWChannelsCount: UInt32 = UInt32.max

    var vertexIndexes: Data?

    var stripLength: UInt32 = UInt32.max

    var stripsCount: UInt32 = UInt32.max

    var vertex: Data?

    var normals: Data?

    var tangents: Data?

    var binormals: Data?

// and so on ...
}

每当我创建一个新的Data对象时,它的'data'字段中应该包含不同的数据类型。解决此类问题的最佳方法是什么?

我的想法: 1)AbstractFactory模式:我可以创建基类Data和许多子类,如DataInt,DataFloat等,但这意味着我需要为每个支持类型创建子类(int32,int8和15种类型)。

2)泛型:我可以像这个类Data一样定义Data,但之后我的Mesh类变得依赖于Data类,因为没有方法可以定义没有type参数的泛型类。

3)UnsafePointer我可以使用这个指针存储数据但是我不确定如果从中读取信息的NSData对象被解除分配,数据是否会持续存在。还有从UnsafePointer到实际类型的性能类型转换。

非常感谢这种情况的任何其他做法。

P.S。我正在开发存储3D图形数据的Pod文件的解析器。 可以找到POD文件格式规范here作为参考。

3 个答案:

答案 0 :(得分:1)

为什么不使用Any?:

class Data {
    var dataType: PodDataType = PodDataType.None
    var componentsCount: UInt32 = 0
    var stride: UInt32 = 0
    var data: Any?
}

但我认为这是enum with associated values的好用例:

enum PodData {
    case Ints([Int])
    case Floats([Float])
    // ...
    case None
}

答案 1 :(得分:0)

Swift中通常采用的方法是为每种类型创建一个属性,并为每个实例使用一个属性。简单,安全,非常少的冗余。

唯一可行的替代方法是找到一种可以描述您想要的所有数据类型的数据格式,例如: String。但是你必须花时间设计可靠的阅读和写作转换。显然,你必须付出高效的代价。

答案 2 :(得分:-1)

在我看来,你可以结合使用第一种和第二种方法。

使用具有泛型的原始类的具体类的抽象工厂模式。它会让你的生活更轻松。

class BaseData {

}

class PrimitiveData<T> : BaseData {

}

class UserDefinedData : BaseData {

}
相关问题