使用异步显示工具包批量获取 / cloudkit

batch fetching with async display kit / cloudkit

我正在尝试实现批量获取以与 cloudkit 和异步显示工具包集成。但是,当我尝试四处滚动时,出现此错误:

[NSOperationQueue addOperation:]: 操作完成,无法入队'

知道这会发生吗?谢谢!

这些是我的网络电话:

var thisCursor : CKQueryCursor?
var newQueryOP : CKQueryOperation?

func pullPosts(curLocation: CLLocation, completionHandler: @escaping(([PostMap]) -> Bool)) {
    print("------------PULLING POSTS (1ST PULL) ----------------")
    let location = curLocation

    var annotations : [PostMap] = [PostMap]()

    //let curLocation = mapLocationManager.getCurrentLocation()
    let locationPredicate = NSPredicate(format: "distanceToLocation:fromLocation:(%K, %@) < %f", "Location", location,
                                        CKConstants.loadPinsRadius)
    let query = CKQuery(recordType: "PostMap", predicate: locationPredicate)
    query.sortDescriptors = [CKLocationSortDescriptor(key: "Location", relativeLocation: location)]
    let queryOP = CKQueryOperation(query: query)

    print("SERVER DECIDED QUERY LIMIT  \(queryOP.resultsLimit)")

    queryOP.recordFetchedBlock = { record in
        //MAKE A NEW POST (taken out for brevity)
        annotations.append(postToAdd)
    }

    queryOP.queryCompletionBlock = { [unowned self] (cursor, error) in
        DispatchQueue.main.async {
            if error == nil {
                if completionHandler(annotations) {
                    if cursor != nil {
                        print("THIS CURSOR IS NOT NIL")
                        self.thisCursor = cursor
                        self.newQueryOP = CKQueryOperation(cursor: cursor!)
                    }
                }
            } else {
                print(error)
                print("could not pull posts")
            }
        }
    }

    queryOP.resultsLimit = 15
    CKContainer.default().publicCloudDatabase.add(queryOP)
}

public func continuePullPosts(curLocation: CLLocation, queryOP: CKQueryOperation,
                               annotations: [PostMap], completionHandler: @escaping(([PostMap]) -> Bool)) {
    var annotations = annotations
    print("------------CONTINUE PULLING POSTS ----------------")
    queryOP.recordFetchedBlock = { record in
        //MAKE A NEW POST (taken out for brevity)
        annotations.append(postToAdd)
    }

    queryOP.queryCompletionBlock = { [unowned self] (cursor, error) in
        DispatchQueue.main.async {
            if error == nil {
                if completionHandler(annotations) {
                    if cursor != nil {
                        print("paging posts")
                        self.thisCursor = cursor!
                        self.newQueryOP = CKQueryOperation(cursor: cursor!)
                    }
                }
            } else {
                print(error)
                print("could not pull posts")
            }
        }
    }

    queryOP.resultsLimit = CKConstants.subsequentPullAmount
    CKContainer.default().publicCloudDatabase.add(queryOP)
}

在我的 TableViewController 中:

func shouldBatchFetch(for tableNode: ASTableNode) -> Bool {
    if (pinDataManager.thisCursor == nil) {
        return false
    }; return true
}

func tableNode(_ tableNode: ASTableNode, willBeginBatchFetchWith context: ASBatchContext) {
    var annotations : [PostMap] = [PostMap]()
    pinDataManager.continuePullPosts(curLocation: locationManager.getCurrentLocation(), queryOP: pinDataManager.newQueryOP!, annotations: annotations) { (annotations) -> Bool in
        self.insertNewRowsInTableNode(annotations: annotations)
        context.completeBatchFetching(true)
        return true
    }
}

func insertNewRowsInTableNode(annotations: [MapObject]) {
    let section : NSInteger = 0
    let indexPaths = NSMutableArray()
    let totalPosts = self.postObjects.count + annotations.count
    print(self.postObjects.count)
    print(annotations.count)

    for index in self.postObjects.count...totalPosts - 1 {
        let path = NSIndexPath(row: index, section: section)
        indexPaths.add(path)
    }
    self.postObjects = self.postObjects + annotations
    self.tableNode.insertRows(at: indexPaths as! [IndexPath], with: .none)
}

您正在将一个已完成的操作传递给您的 continuePullPosts 函数,然后尝试将其 re-add 传递给数据库。

相反,您需要保存从第一个操作返回的游标,将该游标传递给 continuePullPosts,然后使用 initWithCursor 创建一个新的 follow-up 操作。

您需要在每次收到游标时继续使用 initWithCursor 创建新操作,直到查询最终完成并且 returns 一个零游标。