【问题标题】:Swift. Is it possible to determining property time at runtime迅速。是否可以在运行时确定属性时间
【发布时间】:2015-09-09 10:14:37
【问题描述】:

我有下一个问题:

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

看起来像这样

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
}

我还有另一个类,它有多个 Data 实例,如下所示:

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 ...
}

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

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

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

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

高度赞赏这种情况的任何其他做法。

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

【问题讨论】:

    标签: ios swift cocoa design-patterns 3d


    【解决方案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
    }
    

    【讨论】:

    • Any如何在运行时判断类型?
    • @AminNegm-Awad 来自dataType 财产。
    • 然后属性决定类型。使用switch 级联?
    • 迟早,我们必须switch 并强制转换以检索有效负载。
    • 在没有switch 的情况下,运行时环境迟早可以做到这一点。
    【解决方案2】:

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

    唯一可行的替代方法是找到一种可以描述您想要的所有数据类型的数据格式,例如String。但是您将不得不投入时间来设计可靠的读写转换。显然,您必须为效率付出代价。

    【讨论】:

    • Swift 中常用的方法,不是常用的方法。
    • 没错。我改变了措辞。
    • 顺便说一句:有我。 e. 17 个属性而不是 1 个不是多余的,而是 1,600 % 的开销。
    • 不,那将是 17 个数据类型,不太可能。另外,您没有在空槽中存储任何数据,因此开销仍然很小。
    • "(int32, int8 和 15 种以上)"
    【解决方案3】:

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

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

    class BaseData {
    
    }
    
    class PrimitiveData<T> : BaseData {
    
    }
    
    class UserDefinedData : BaseData {
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-01
      • 1970-01-01
      • 2013-03-30
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2021-09-24
      相关资源
      最近更新 更多