【问题标题】:Providing custom backing store for instance properties of a Swift class subclassed from NSObject为从 NSObject 子类化的 Swift 类的实例属性提供自定义后备存储
【发布时间】:2020-01-06 06:33:43
【问题描述】:

我有一个类似于this question 中描述的要求。

我想在运行时为从 NSObject 继承的 Swift 类动态生成 getter 和 setter(与 NSManagedObject 在幕后所做的类似)。

该问题的答案提到了@dynamic 的用法,以抑制 Objective-C 编译器 警告,然后还执行方法混合。

此外,当在 Swift 中使用 CoreData 时,我们有 @NSManaged 属性,它告诉 Swift 编译器这个属性存储不是通常的存储,而是有一些由 CoreData 提供的自定义后备存储。

有没有办法类似地告诉 Swift 编译器 我的自定义类属性具有自定义后备存储,而不使用通常的 Swift 提供的存储?

我正在考虑属性包装器来修改存储,但这是正确的方向还是有其他方法?

如果我们使用属性包装器,在使用自定义属性包装器声明属性时,我会觉得有一个特殊的功能令人不快并且想要避免:

@MyCustomPropWrapper(backingStore: someStore) var counter: Int

【问题讨论】:

    标签: objective-c swift nsmanagedobject


    【解决方案1】:

    您可以使用两个 Objective-C 运行时功能执行您所描述的操作:

    关联对象:

    您可以使用关联对象在 Objective-C 对象上动态设置属性。此功能的文档是here,这里是tutorial style guide

    前向调用:

    Objective-C 使用消息样式方法调度。这意味着方法在运行时被解析。相反,默认情况下,Swift 使用静态和 vtable 调度,因此所有链接都是在编译时完成的。但是,您可以通过从 NSObject 扩展来指示 Swift 使用消息传递。

    动态分派提供了提供在编译时未静态定义的方法的实现的机会。其机制是使用forwardInvocation,描述为here

    【讨论】:

    • 当我们将 swift 属性声明为 @objc 动态时,方法调度将用于访问该属性。但是如何修改属性的存储机制呢?
    • 我不希望它们存储在支持 iVar 中,我希望它们存储在字典中。所以当我说@objc dynamic var myInt: Int 时,我想控制 Int 值的存储位置。我在这里有点天真,可能缺乏必要的理解
    • 如果您愿意,您可以使用 forwardInvocation 到一个方法,该方法通过键从单个字典中查找属性。该字典对象需要保留在某处 - 不确定您的要求,但建议对象本身。您必须使用 ObjC 兼容类型,即 NSDictionary。
    • 好的,我会朝这个方向深入研究
    猜你喜欢
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多