gpt4 book ai didi

swift - NSFetchedResultsController sectionNameKeyPath 不遵守 fetchBatchSize

转载 作者:行者123 更新时间:2023-11-28 07:56:32 26 4
gpt4 key购买 nike

抱歉核心数据新手...

我在 UITableViewController 上使用 NSFetchedResultsController。实体中的数据包含时间戳。作为 sectionID 我想在节标题中使用日期。但是,当我使用 sectionNameKeyPath 时,Core Data 会加载所有数据,而不是考虑 fetchBatchSize

我想要的是可能的吗?如果是的话,我做错了什么。如果使用 fetchedResultsController 无法做到这一点,还有哪些替代方案?

fetchedResultController:

class func transactionsResultController(wallet: Wallet, batchSize: Int? = nil) -> NSFetchedResultsController<Transaction> {
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext

let fetchedResultsController: NSFetchedResultsController = { () -> NSFetchedResultsController<Transaction> in
let fetchRequest: NSFetchRequest<Transaction> = Transaction.fetchRequest()

fetchRequest.predicate = NSPredicate(format: "ANY wallet == %@", wallet)

fetchRequest.fetchBatchSize = batchSize ?? 20

let sortDescriptor = NSSortDescriptor(key: #keyPath(Transaction.timestamp), ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]

let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: "sectionIdentifier", cacheName: nil)

do {
try aFetchedResultsController.performFetch()
} catch let error {
debug(error)
}
return aFetchedResultsController
}()

return fetchedResultsController }

部分标识符:

extension Transaction{

var sectionIdentifier: String {
let date = self.timestamp!.timestampToUTCDate(currency: (self.senderId?.currency!)!)
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(abbreviation: "en_US_POSIX")
var components = DateComponents()
let comps = Calendar.current.dateComponents([.year, .month, .day], from: date)
components.day = comps.day
components.month = comps.month
components.year = comps.year
let calendar = Calendar.current
let reconstructedDate = calendar.date(from: components)!

dateFormatter.dateFormat = "dd"
let prettyDay = dateFormatter.string(from: reconstructedDate)
dateFormatter.dateFormat = "MMMM"
let prettyMonth = dateFormatter.string(from: reconstructedDate)
dateFormatter.dateFormat = "YYYY"
let prettyYear = dateFormatter.string(from: reconstructedDate)

if (calendar.isDateInToday(reconstructedDate)){
return "Today"
}
else if (calendar.isDateInYesterday(reconstructedDate)){
return "Yesterday"
}

return "\(prettyDay) \(prettyMonth) \(prettyYear)"
} }

感谢您花时间阅读和帮助 ;)

最佳答案

fetchedResultsController 不考虑 batchSize。 fetchedResultsController 的工作方式是使用谓词进行提取,然后监视上下文以查看项目何时添加或删除到 fetchedObjects 列表并进行相应更新。如果改变的项目通过谓词,但不在列表中,它是一个插入;如果更改的项未通过谓词,但在列表中,则为删除,否则为更新或移动。如果它遵守批量大小,那么 fetchedResultsController 就很难知道通过谓词但不在列表中的更改项是插入项还是通过 batchSize 的项。

这里有两种可能的解决方案:

  1. fetchedResultsController 获取具有 batchSize 限制的所有内容。然后在您的用户界面中限制您显示的数量。不要通过在 tableView 中减少行来限制它 (NUMBER_OF_ROWS -= min(REAL_NUMBER, SIZE_LIMIT)。有太多烦人的边缘情况你必须跟踪 - 比如移动和插入,推送会将项目推出在底部列出,并为未显示的项目委托(delegate)事件。它们不是很难处理,但它们可以加起来,如果你搞砸了,tableView 将停止工作。声明要容易得多indexPath 在特定索引上方的行高为 0。这样您仍然可以像往常一样响应委托(delegate)的 fetchedResultsController 事件,但 UI 不会显示单元格。

  2. 添加另一个谓词,将您的结果限制为所需的数量。例如,如果您的项目是按日期排序的,并且您只想要最近的添加谓词“date > CUT_OFF_DATE”。要确定要使用的正确日期削减,您可以执行一次提取,其中 batchSize=1 并且 batchOffset 等于您要显示的最大数量。然后在谓词中使用该对象的日期来创建 fetchedResultsController。虽然在加载 Controller 时会遵守限制,但随着插入的项目越来越多,显示的数量会增加,超过初始显示限制。

如果你有很多项目并且想限制进入内存的数量,第二个选项更好。

如果你想限制每个部分显示的数量(不仅仅是整个表格的全局限制)那么第一个选项可以支持,但第二个选项不能。

关于swift - NSFetchedResultsController sectionNameKeyPath 不遵守 fetchBatchSize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47894389/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com