ios - fetchBatchSize 不适用于 NSFetchRequest

标签 ios swift xcode core-data nsfetchrequest

我想了解为什么 fetchBatchSize 无法与 NSFetchRequest 一起正常工作。

在初始获取时,加载故障数组后,数据数组将按batchSize循环加载,直到加载所有数据,而不是只加载所需的数据。使用 coreData 工具或编辑运行方案可以清楚地显示在批量大小项目数的循环中加载的所有项目数据,直到加载所有数据,而不是仅加载 tableView 中出现的那些行的数据。

预期结果:

预计故障数组中的所有项目都会被加载,然后仅加载第一批数据。

实际结果:

所有项目都加载到故障数组中,然后在任何滚动之前以批量大小的循环批处理加载所有数据。

这是我创建的示例项目 viewController 来演示这一点:

import UIKit
import CoreData

class BatchTestTableViewController: UITableViewController {

    var context: NSManagedObjectContext!
    var items: [Item]?

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UINib(nibName: "BatchTableViewCell", bundle: nil), forCellReuseIdentifier: "BatchTableViewCell")

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        self.context = appDelegate.persistentContainer.viewContext

        self.initializeItems()

        if items != nil {
            if items!.count == 0 {
                for i in 0..<10000 {
                    let entityDescription =  NSEntityDescription.entity(forEntityName: "Item", in: context)
                    let item = Item(entity: entityDescription!, insertInto: self.context)
                    item.objectId = UUID().uuidString
                    item.itemId = UUID().uuidString
                    item.itemName = "\(i)"

                }
                try? context.save()
                self.initializeItems()
            }
        }
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if items != nil {
            return items!.count
        }
        return 0
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "BatchTableViewCell", for: indexPath) as! BatchTableViewCell
        let item = self.items![indexPath.row]
        cell.itemNameLabel.text = item.itemName
        return cell
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 50
    }

    // MARK: - Helper Methods

    func initializeItems() {
        let request = NSFetchRequest<Item>(entityName: "Item")
        let messageSort = NSSortDescriptor(key: "itemName", ascending: true)
        request.fetchBatchSize = 20
        request.sortDescriptors = [messageSort]

        do {
            self.items = try context.fetch(request)
        } catch {
            print("Could not fetch \(error)")
        }
    }

}

这是从 CoreData Instruments 读取的数据:

enter image description here

从上面的 coredata Instrument 图像中可以看出,所有数据都以 20 个批量大小的循环加载,直到在 tableView 滚动之前加载所有 10,000 个项目。

最佳答案

fetchBatchSize 不会限制您的数据获取。在您的情况下,它使 fetchRequest 能够批量获取 20 个数据。您可以使用此功能来限制应用程序中的工作数据集。与 fetchLimit 结合使用,您可以创建任意结果集的子范围。您应该一起使用fetchLimit

    request.fetchLimit = 20

From Apple doc

When the fetch is executed, the entire request is evaluated and the identities of all matching objects recorded, but only data for objects up to the batchSize will be fetched from the persistent store at a time. The array returned from executing the request is a proxy object that transparently faults batches on demand. (In database terms, this is an in-memory cursor.)

关于ios - fetchBatchSize 不适用于 NSFetchRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51228685/

相关文章:

swift - 你能给 UIStackView 边框吗?

swift - 当我尝试发出 GET 请求时出现 "Execution was interrupted, reasno: EXC_BAD_INSTRUCTION"错误

swift @objc 和选择器 : compiler error with type returned from selector

ios - 更新到 Fabric 后,Mac App 没有配置我的项目

android - react native : Dev Server IP iOS vs Android

ios - 保存按钮状态

ios - 更新了用户位置 : MKUserLocation for google maps ios swyft

java - Swift 中的抽象类

ios - 如何区分同一 UIViewController 中多个对象的 iOS UIKit 数据源和委托(delegate)方法?

ios - 使用反射访问模型类的静态变量