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

标签 swift uiscrollview cloudkit asyncdisplaykit batch-fetching

我正在尝试实现批量获取以与 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 函数,然后尝试将其重新添加到数据库中。

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

每次收到游标时,您都需要使用 initWithCursor 继续创建新操作,直到查询最终完成并返回 nil 游标。

关于swift - 使用异步显示工具包/cloudkit 批量获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49206327/

相关文章:

ios - CKFetchRecordChangesOperation-更多即将到来

ios - 使用对象的 Swift 二维数组初始化

swift - 遍历从 MongoDB 获取的字符串数组

ios - 在 UIButton 上组合扩展和自定义类会产生问题

ios - 如何将 ScrollView 中的图像上传到网络服务器上?

ios - 无法将 View 添加到 ScrollView

javascript - 使用 CloudKit JS 创建引用

php - 特殊字符插入数据库

ios - 在 Swift 中嵌套 UIScrollView

ios - 如何将字典保存到cloudkit