类型安全的swift NSEntityDescriptor insertNewObjectForEntityForName(_:inManagedObjectContext :)

时间:2015-03-05 04:11:52

标签: swift generics core-data

NSEntityDescriptor的{​​{1}}返回insertNewObjectForEntityForName(_:inManagedObjectContext:)。如果我将我的实体命名为与它们的AnyObject子类相同,有没有办法在NSManagedObject上创建一个返回正确类型的通用扩展方法,以便消费者不需要向下转换?

1 个答案:

答案 0 :(得分:1)

public extension NSManagedObject {
    public class func entityName() -> String {
        let moduledName = self.description()
        if let firstDotRange = moduledName.rangeOfString(".") {
            return moduledName.substringFromIndex(firstDotRange.endIndex)
        } else {
            return moduledName
        }
    }

    public class func insert(#managedObjectContext: NSManagedObjectContext) -> Self {
        return _insert(managedObjectContext: managedObjectContext)
    }

    private class func _insert<SelfType>(#managedObjectContext: NSManagedObjectContext) -> SelfType {
        return NSEntityDescription.insertNewObjectForEntityForName(entityName(),
            inManagedObjectContext: managedObjectContext) as SelfType
    }
}

理想情况下,我们只需编写insert(managedObjectContext:),如:

public class func insert(#managedObjectContext: NSManagedObjectContext) -> Self {
    return NSEntityDescription.insertNewObjectForEntityForName(entityName(),
        inManagedObjectContext: managedObjectContext) as Self
}

但这失败了:

'Self' is only available in a protocol or as the result of a class method; did you mean 'NSManagedObject'?
            inManagedObjectContext: managedObjectContext) as Self
                                                             ^~~~
                                                             NSManagedObject

因此,我们只是将其作为原始insert(managedObjectContext:)方法的结果而保留,并让swift的泛型类型推断使SelfType成为合适的类型。