Swift:NSClassFromString 和 NSStringFromClass 对于 NSManagedObjects 的行为不同

标签 swift core-data reflection

NSStringFromClass为类引用提供完全限定的类名,例如 <ClassName>".self"

NSStringClassFromString提供类的类引用 AnyClass对于完全限定的类名,如 <AppId>"."<ClassName">

但是对于 NSManagedObject 的子类它的行为有所不同.

假设 AppId 是“MyApp”。

class Foo: NSObject {}

@objc(Bar)
class Bar: NSManagedObject {}

print(NSStringFromClass(Foo.self))        // MyApp.Foo
print(NSStringFromClass(Bar.self))        // Bar

print(NSClassFromString("Foo"))           // nil
print(NSClassFromString("Bar"))           // MyApp.Bar
print(NSClassFromString("MyApp.Foo"))     // MyApp.Foo
print(NSClassFromString("MyApp.Bar"))     // nil

在为 NSClassFromString 创建输入时,这可能会导致问题动态地,例如通过将“AppId”与 MyClass.self 确定的类名连接起来。看来 NSManagedObject 的子类不属于 Apps 命名空间。

这很有趣。这些功能是可逆的。

let fco = NSClassFromString(NSStringFromClass(Foo.self))
let fct = NSClassFromString(NSStringFromClass(fco!))
// fco == fct    

let bco = NSClassFromString(NSStringFromClass(Bar.self))
let bct = NSClassFromString(NSStringFromClass(bco!))
// bco == bct

但是中间结果有所不同,正如您在上面的列表中看到的那样。

严重问题:这是错误还是功能?如果是一个功能,原因和优点是什么。

最佳答案

我从 Playground 得到的结果与你的结果不同......

import CoreData

class Foo: NSObject {
    required override init() {
        super.init()
    }
    let test = 100
}

@objc(Bar)
class Bar: NSManagedObject {
    required convenience init() {
        self.init(entity: NSEntityDescription(), insertIntoManagedObjectContext: nil)
    }
}

let s1 = NSStringFromClass(Foo.self) // "__lldb_expr_xxx.Foo"
let s2 = NSStringFromClass(Bar.self) // "Bar"

let cFooType = NSClassFromString(s1) as! Foo.Type
let c = cFooType.init()
c.test == 100 // true

// to create Bar, you have to implement a little bit more, but the
// strategy could be the same

// the init for class Bar is there just to compile, you need real values for entity an insertIntoManagedObjectContext ....

关于Swift:NSClassFromString 和 NSStringFromClass 对于 NSManagedObjects 的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34436035/

相关文章:

ios - 添加数组以在 Swift : SpriteKit 的 for 循环中移动图像组

ios - 使用谓词获取核心数据中 parent 的所有 child

c# - 通过反射修饰DataType属性

xcode - 为什么 XCode 给我一个 'unrecognized selector' 错误?

ios - 访问 UICollectionView 的父 UIViewController

swift - 如何正确地将 3rd 方库委托(delegate)转换为 RxSwift Observable

java - java中的.class文件

ios - 在串行队列上获取 CoreData 期间崩溃

objective-c - 使用获取的请求排序描述符

接口(interface)的 TypeScript 反射