【问题标题】:Can't fetch optional variables with class_copyPropertyList in Swift无法在 Swift 中使用 class_copyPropertyList 获取可选变量
【发布时间】:2014-08-21 08:11:00
【问题描述】:

我使用以下类 Serializable 将类 Object 转换为 Json。见LINK

 var aClass : AnyClass? = self.dynamicType
    var propertiesCount : CUnsignedInt = 0
    let propertiesInAClass : UnsafePointer<objc_property_t> = class_copyPropertyList(aClass, &propertiesCount)
    var propertiesDictionary : NSMutableDictionary = NSMutableDictionary()

    for var i = 0; i < Int(propertiesCount); i++ {
        var property = propertiesInAClass[i]
        var propName = NSString(CString: property_getName(property), encoding: NSUTF8StringEncoding)
        var propType = property_getAttributes(property)
        var propValue : AnyObject! = self.valueForKey(propName);
   /* ... */ 
 }

它工作正常,但是当类包含可选值时,class_copyPropertyList(aClass, &amp;propertiesCount) 看不到它。

考虑以下基本类:

class Person : Serializable{
  var age = 1
  var name = "no name yet"
  var hasMail:Bool?

}

即使我会写:

var person = Person()
person.hasMail =  true

我只得到:

age
name 

为了让它工作,我需要写var hasMail:Bool = false


对于游乐场(复制/粘贴)

class User : NSObject{
    var age = 1
    var name = "no name yet"
    var hasMail:Bool?

}

var person = User()
person.hasMail =  true

 var aClass : AnyClass? = person.dynamicType
var propertiesCount : CUnsignedInt = 0
let propertiesInAClass : UnsafeMutablePointer<objc_property_t> = class_copyPropertyList(aClass, &propertiesCount)

 println(propertiesInAClass)

for var i = 0; i < Int(propertiesCount); i++ {
    var property = propertiesInAClass[i]
    var propName = NSString(CString: property_getName(property), encoding: NSUTF8StringEncoding)
    println(propName)
}

如何获取可选名称?

谢谢,

【问题讨论】:

  • 即使没有答案:读取类的属性列表进行“自动”序列化是个坏主意。我编写了大量包含计算属性的类,这些属性不应该被序列化到任何地方。
  • @AminNegm-Awad 在 Java 世界中,您有插件 Gson 可以将任何类转换为 Json,无论类多么复杂。所以停止尝试自动序列化的建议是没有意义的。还是谢谢
  • 这个建议是没有意义的,因为java中有插件?有趣的笑话……

标签: objective-c swift


【解决方案1】:

Foundation 提供了从BoolNSNumber 的桥(以及IntString 等的桥),但它不提供Bool? 的桥。这就是为什么它对 Objective-C 不可见。如果您尝试用@objc 注释hasMail,它会报错,而它适用于其他属性。

【讨论】:

  • 感谢您的精彩解释。所以这简直是不可能的吗? :(
【解决方案2】:

在带有 XC9.2 的 Swift 4 中,我在 Obj-C 中看到了 Swift 选项。这是我使用的代码:

在 Swift 类中:

    @objc var optionalNumber:NSNumber?

在 Objective-C 代码中:

Class              object         =   MyClass.class;
unsigned int       numProperties  =   0;
objc_property_t*   classProps     =   class_copyPropertyList(object, &numProperties);

for (NSInteger index = 0; index < numProperties; index++)
{
      objc_property_t     aProperty   =   classProps[index];
    //...
}

在我看到的那个点:

(lldb) po 属性

"T@\"NSNumber\",N,&,VoptionalNumber"

当我尝试将其模型映射到可选 NSNumber 时,我仍然遇到 CoreData 崩溃的问题,但我可能最终会在运行时将 NSNumber 映射到小数以解决问题(如果我使用非可选swift 类中的 NSNumber 一切正常,所以它看起来像一个 CoreData 错误)。

作为参考,这是为 CoreData 实体模型提供自动 Class 的代码的一部分,而无需使 xcdatamodeld 与动态代码保持同步。

【讨论】:

    猜你喜欢
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多