如何在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??梢栽诰庉嫐v史中找到早期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 關注
- 555 瀏覽
添加回答
舉報
0/150
提交
取消