如何在NSManagedObject Swift扩展中创建托管对象子类的实例?当创建一个扩展助手来NSManagedObject创建一个新的托管对象子类时,swift提供了Self模仿的类型,instancetype这很好,但我似乎无法进行类型转换AnyObject。下面的代码没有编译错误'AnyObject'不能转换为'Self'救命?extension NSManagedObject{
class func createInContext(context:NSManagedObjectContext) -> Self {
var classname = className()
var object: AnyObject = NSEntityDescription.insertNewObjectForEntityForName(classname, inManagedObjectContext: context)
return object }
class func className() -> String {
let classString = NSStringFromClass(self)
//Remove Swift module name let range = classString.rangeOfString(".", options: NSStringCompareOptions.CaseInsensitiveSearch, range: Range<String.Index>(start:classString.startIndex, end: classString.endIndex), locale: nil)
return classString.substringFromIndex(range!.endIndex)
}}
3 回答
慕沐林林
TA贡献2016条经验 获得超9个赞
(现在更新为Swift 3/4。可以在编辑历史中找到早期Swift版本的解决方案。)
您可以使用unsafeDowncast
到的返回值转换NSEntityDescription.insertNewObject()
到Self
(这是该方法实际上是所谓的类型):
extension NSManagedObject { class func create(in context: NSManagedObjectContext) -> Self { let classname = entityName() let object = NSEntityDescription.insertNewObject(forEntityName: classname, into: context) return unsafeDowncast(object, to: self) } // Returns the unqualified class name, i.e. the last component. // Can be overridden in a subclass. class func entityName() -> String { return String(describing: self) }}
然后
let obj = YourEntity.createInContext(context)
工作和编译器推断obj
正确的类型YourEntity
。
手掌心
TA贡献1942条经验 获得超3个赞
这是通过实现初始化方法(使用Xcode 7.1测试)来解决问题的不同方法:
extension NSManagedObject { // Returns the unqualified class name, i.e. the last component. // Can be overridden in a subclass. class func entityName() -> String { return String(self) } convenience init(context: NSManagedObjectContext) { let eName = self.dynamicType.entityName() let entity = NSEntityDescription.entityForName(eName, inManagedObjectContext: context)! self.init(entity: entity, insertIntoManagedObjectContext: context) }}
Init方法具有隐式返回类型,Self
并且不需要强制转换技巧。
let obj = YourEntity(context: context)
创建该YourEntity
类型的对象。
Swift 3/4更新:
extension NSManagedObject { // Returns the unqualified class name, i.e. the last component. // Can be overridden in a subclass. class func entityName() -> String { return String(describing: self) } convenience init(context: NSManagedObjectContext) { let eName = type(of: self).entityName() let entity = NSEntityDescription.entity(forEntityName: eName, in: context)! self.init(entity: entity, insertInto: context) }}
慕的地10843
TA贡献1785条经验 获得超8个赞
在Swift 2中,有一个使用协议和协议扩展的非常智能的解决方案
protocol Fetchable{ typealias FetchableType: NSManagedObject static var entityName : String { get } static func createInContext(context: NSManagedObjectContext) -> FetchableType}extension Fetchable where Self : NSManagedObject, FetchableType == Self{ static func createInContext(context: NSManagedObjectContext) -> FetchableType { return NSEntityDescription.insertNewObjectForEntityForName(entityName, inManagedObjectContext: context) as! FetchableType }}
在每个NSManagedObject
子类中添加协议Fetchable
并实现该属性entityName
。
现在该函数MyEntity.createInContext(…)
将返回正确的类型而无需进一步的类型转换。
- 3 回答
- 0 关注
- 524 浏览
添加回答
举报
0/150
提交
取消