Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 通过fetchedResultsController处理核心数据中的大型数据库_Swift_Sqlite_Core Data_Nsfetchedresultscontroller_Uisearchbardelegate - Fatal编程技术网

Swift 通过fetchedResultsController处理核心数据中的大型数据库

Swift 通过fetchedResultsController处理核心数据中的大型数据库,swift,sqlite,core-data,nsfetchedresultscontroller,uisearchbardelegate,Swift,Sqlite,Core Data,Nsfetchedresultscontroller,Uisearchbardelegate,也许有人有处理大型核心数据库的经验(我的数据库中有32k行,我需要向用户显示所有这些数据库并在其中进行一些搜索),当我尝试将数据库读入我的fetchedResultsController时,我有3-5秒的延迟,我如何解决这个问题? 我可以在后台线程中阅读此基础吗? 或者,如果我通过关系在某些部分上分离我的基础,这有帮助吗? 我尝试在视图中加载我的基础 override func viewDidAppear(_ animated: Bool) { DispatchQueue

也许有人有处理大型核心数据库的经验(我的数据库中有32k行,我需要向用户显示所有这些数据库并在其中进行一些搜索),当我尝试将数据库读入我的fetchedResultsController时,我有3-5秒的延迟,我如何解决这个问题? 我可以在后台线程中阅读此基础吗? 或者,如果我通过关系在某些部分上分离我的基础,这有帮助吗? 我尝试在视图中加载我的基础

    override func viewDidAppear(_ animated: Bool) {
        DispatchQueue.main.async {
            self.connectFetchedRequest()
            self.tableView.reloadData()
            self.indicatorLoad.stopAnimating()
        }
    }

    func connectFetchedRequest() {
        do {
            try self.fetchedResultsController.performFetch()
        }catch {
            print(error)
        }
    }
对于基本搜索,我使用UISearchBarDelegate方法(但在搜索文本中添加字符时仍有一些“滞后”)

我使用以下代码创建了fetchedResultsController

    lazy var context: NSManagedObjectContext = {
        let appDelegate = (UIApplication.shared.delegate as? AppDelegate)
        return appDelegate!.managedObjectContext
    }()

    lazy var fetchedResultsController: NSFetchedResultsController<CardsBaseClass> = {
        let fetchRequest = NSFetchRequest<CardsBaseClass>(entityName: "CardsBase")
        let sortDescriptor = NSSortDescriptor(key: "cardName", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]

        fetchRequest.fetchBatchSize = 50
        fetchRequest.returnsObjectsAsFaults = false

        let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.context, sectionNameKeyPath: nil, cacheName: nil)
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }()
predicateArrayClass.addPredicate(predicate: predicateType)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateTableViewByNewPredicate"), object: nil, userInfo: nil)
self.dismiss(animated: true, completion: nil)
在这里,我调用了更新fetchResultController func

func updateTableViewByNewPredicate() {
        searchController.searchBar.text! = ""
        let predicateArray = predicateArrayClass.arrayOfPredicates
        block = DispatchWorkItem {
            self.fetchedResultsController.fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicateArray)
            self.connectFetchedRequest()
            DispatchQueue.main.async(execute: {
                self.tableView.reloadData()
            })
        }
        DispatchQueue.global(qos: .background).async(execute: block!)
}

以下是一些指导原则:

  • 使用批处理。将提取请求的
    fetchBatchSize
    设置为
    50
    ,将
    returnsObjectsAsFaults
    设置为
    NO
  • 在表格视图中使用估计高度。
    estimatedRowHeight
    -tableView:estimatedheightforrowatinexpath:
    UITableViewDelegate
    都可以

  • 这将阻止每次重新加载时加载内存中的所有32K记录。

    以下是一些准则:

  • 使用批处理。将提取请求的
    fetchBatchSize
    设置为
    50
    ,将
    returnsObjectsAsFaults
    设置为
    NO
  • 在表格视图中使用估计高度。
    estimatedRowHeight
    -tableView:estimatedheightforrowatinexpath:
    UITableViewDelegate
    都可以

  • 这将阻止每次重新加载时加载内存中的所有32K记录。

    这不是因为您有32K条记录。那不算大。问题在于,您显然试图使用字符串属性对这些记录进行排序:

    let sortDescriptor = NSSortDescriptor(key: "cardName", ascending: true)
    
    按字符串值对32k记录进行排序是一项艰巨的工作。这需要时间。有两种加速的可能性:

  • 如果可能,请按数字或日期属性而不是字符串进行排序。这要快得多。如果您的数据没有有用的数字属性,也许您可以补足一个,以获得相同的排序结果
  • 通过选中模型编辑器中的“已索引”框,告知核心数据为此属性编制索引。这将有所帮助,但不如对数值属性进行排序

  • 这不是因为你有32k张唱片。那不算大。问题在于,您显然试图使用字符串属性对这些记录进行排序:

    let sortDescriptor = NSSortDescriptor(key: "cardName", ascending: true)
    
    按字符串值对32k记录进行排序是一项艰巨的工作。这需要时间。有两种加速的可能性:

  • 如果可能,请按数字或日期属性而不是字符串进行排序。这要快得多。如果您的数据没有有用的数字属性,也许您可以补足一个,以获得相同的排序结果
  • 通过选中模型编辑器中的“已索引”框,告知核心数据为此属性编制索引。这将有所帮助,但不如对数值属性进行排序

  • 您是否可以编辑问题以添加创建“获取结果”控制器的代码?如何配置它可能是一个关键的细节。添加了,而且我使用NSFetcherResultControllerDelegate方法更新tableView数据(controllerWillChangeContent、controllerDidChangeContent和didChangeObject)。我通过“茶壶”在答案中添加了代码,但加载时间仍然是几秒钟扫描您是否编辑问题以添加代码,在何处创建获取的结果控制器?如何配置它可能是一个关键的细节。添加了,而且我使用NSFetcherResultControllerDelegate方法更新tableView数据(controllerWillChangeContent、controllerDidChangeContent和didChangeObject)。我用“茶壶”在答案中添加了代码,但加载时间仍然是几秒钟。谢谢,现在使用base更好,但在base连接时,在开始时仍有一些加载时间,解决这个问题是真的,还是需要在fetchedResultsController中连接基础?@Skie您可以通过执行后台提取请求并将NSManagedObjects传递到主线程来预热NSPersistentStoreCoordinator的缓存,可能就在应用程序启动之后。谢谢,使用base现在更好了,但在base连接时,在开始时仍有一些加载时间,是真的要解决这个问题,还是需要在fetchedResultsController中连接base?@Skie您可以通过执行后台提取请求并将NSManagedObjects传递到主线程来预热NSPersistentStoreCoordinator的缓存,也许就在应用程序启动之后。谢谢,我为我的“cardName”添加了“indexed”,现在所有的基都被很快地排序了。我有一个新问题。我从其他viewController中更新了一些谓词,以便在此基础上进行过滤,第一个过滤器加载大约10秒,但是当我使用此和/或新谓词过滤器时,我只有1秒的延迟来重新编辑搜索结果。为什么会这样?可能是我调用了内存中的新基(我试图捕捉到这一点,但我没有调用任何新的NSFetchRequestController),或者这不是更新fetchedResultsController的好方法?谢谢,我为我的“cardName”添加了“indexed”,现在所有基都被很快地排序了。我有一个新问题。我从其他viewController中更新了一些谓词,以便在此基础上进行过滤,第一个过滤器加载大约10秒,但是当我使用此和/或新谓词过滤器时,我只有1秒的延迟来重新编辑搜索结果。为什么会这样?也许我调用了内存中的新基(我试图捕获它,但我没有调用任何新的NSFetchRequestController),或者它不是更新fetchedResultsController的好方法?