【问题标题】:Return as CustomManagedObjectClass NSFetchedResultsController<NSManagedObject> at base NSManagedObject class在基础 NSManagedObject 类中作为 CustomManagedObjectClass NSFetchedResultsController<NSManagedObject> 返回
【发布时间】:2018-04-23 15:24:32
【问题描述】:

这是我的第一个Swift 项目,也是CoreDataSwift 不像 Objective C 中的 return instancetype。 在Swift - CoreData 类中,我使用NSManagedObject 的通用基类。在那里我实现了一个class 函数。

class func FRCWith(sortArray: [NSSortDescriptor], predicate: NSPredicate? = nil, mainContext: NSManagedObjectContext = CoreDataManager.shared.managedObjectContext) -> NSFetchedResultsController<NSManagedObject> {
    let className = self.nameOfTheClass
    let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest.init(entityName: className)
    fetchRequest.sortDescriptors = sortArray
    fetchRequest.fetchBatchSize = 4

    if let predicateValue = predicate {
        fetchRequest.predicate = predicateValue
    }

    let fetchedResultsController: NSFetchedResultsController<NSManagedObject> = NSFetchedResultsController.init(fetchRequest: fetchRequest, managedObjectContext: mainContext, sectionNameKeyPath: nil, cacheName: nil)

    do {
        try fetchedResultsController.performFetch()
    } catch {
        print(error.localizedDescription)
    }

    return fetchedResultsController
}

我想返回NSFetchedResultsController&lt;customCoreDataClass&gt; 而不是普通的NSFetchedResultsController&lt;NSManagedObject&gt;

var schoolvalue: NSFetchedResultsController<SchoolDetails> = SchoolDetails.FRCWith([sort])
var schoolvalue: NSFetchedResultsController<StudentDetails> = StudentDetails.FRCWith([sort], preidcate)

现在我像这样在for loop 中使用并检查FRC as! customClass

let loopValue: SchoolDetails = someFRC.object(at: IndexPath.init(row: value, section: 0)) as! SchoolDetails

找到某种solution in StackOverflowT那个东西,我不明白。

这样的方法有可能吗?

谢谢@Paulw11 的回答。

初始化时应用随机崩溃

let fetchedResultsController: NSFetchedResultsController<T> = NSFetchedResultsController<T>(fetchRequest: fetchRequest, managedObjectContext: mainContext, sectionNameKeyPath: nil, cacheName: nil)

from below answer。 因为

let fetchRequest:NSFetchRequest<T> = T.fetchRequest() as! NSFetchRequest<T>\\ line return nil. There is no crash below iOS 10.x.

仅在从 App Store 或 Testflight 下载时发生。

【问题讨论】:

  • 那个 T 东西是 Swift 泛型。它们在 Apple 的 Swift 书中有所描述。当你说NSFetchedResultsController&lt;StudentDetails&gt; 时,你已经在使用泛型了
  • 感谢@Paulw11 提供的信息。在另一个答案中func fetchObjects&lt;T:NSManagedObject where T:NamedManagedObject&gt;(entity:T.Type, predicate:NSPredicate? = nil, sortDescriptors:NSSortDescriptor[]? = nil) -&gt; T[]? 有没有办法将这个NamedManagedObject 静态类作为动态类来克服?

标签: ios core-data nsfetchedresultscontroller nsfetchrequest base-class


【解决方案1】:

您可以为此使用 Swift 泛型。您指定一个占位符,通常使用T,但不一定是,它“代表”将使用的实际类。在这种情况下,您需要指定 T 必须是 NSManagedObjectNSManagedObect 的子类

将你的函数声明为:

class func FRCWith<T: NSManagedObject>(sortArray: [NSSortDescriptor], predicate: NSPredicate? = nil, mainContext: NSManagedObjectContext) throws -> NSFetchedResultsController<T> {
    let fetchRequest:NSFetchRequest<T> = T.fetchRequest() as! NSFetchRequest<T>
    fetchRequest.sortDescriptors = sortArray
    fetchRequest.fetchBatchSize = 4

    fetchRequest.predicate = predicate

    let fetchedResultsController: NSFetchedResultsController<T> =
        NSFetchedResultsController<T>(fetchRequest: fetchRequest, managedObjectContext: mainContext, sectionNameKeyPath: nil, cacheName: nil)

    try fetchedResultsController.performFetch()

    return fetchedResultsController
}

然后您可以使用以下方法调用它:

if let frc: NSFetchedResultsController<SchoolDetails> = try? CD.FRCWith(sortArray: [], mainContext: moc) {
    // Do something with results
    if let schoolDetails = frc.fetchedObjects?.first {
        // schoolDetails will be an instance of SchoolDetails
    }
}

请注意,我已将函数声明为throws,而不是将错误隐藏在函数内。

【讨论】:

  • 谢谢,您能分享一下类似(某种)文档或示例的内容吗?因为 ` where T:NamedManagedObject` 如果我删除并尝试过,就不需要这个问题了。
  • 您链接到的任一答案是使用NamedManagedObject 协议来获取实体。我通过使用现在可用的T.fetchRequest() 避免了这种情况; T 已经知道它自己的实体,因此不需要明确指定它。
  • let fetchRequest:NSFetchRequest&lt;T&gt; = T.fetchRequest() as! NSFetchRequest&lt;T&gt; 这一行返回 nil 并检查了所有 coredata 类都有@nonobjc public class func fetchRequest() -&gt; NSFetchRequest&lt;name&gt; { return NSFetchRequest&lt;name&gt;(entityName: "name") }。你知道是什么问题吗?此外,应用程序支持 iOS 9.x 添加了可用的 ios 版本,用于更大或更小,在低于 iOS 10 时不会崩溃。
  • 不是每次@Paulw11都会出现,只有从App store或者Testflight下载的时候才会出现,所以发现这个问题需要时间。
猜你喜欢
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 1970-01-01
  • 2014-06-15
  • 2010-12-02
相关资源
最近更新 更多