处理cloudkit错误时未捕获的异常'NSInvalidArgumentException'

时间:2018-10-17 21:57:58

标签: swift

我的应用程序崩溃并出现以下错误,我正在尝试复制它,但是我不能,所以有人可以提供一些有关出了什么问题的见解吗?

class ViewController: UIViewController {
 //all the usual class methods here

 @objc func getData() {
self.array = []
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: “Product”, predicate: predicate)

let queryOperation = CKQueryOperation(query: query)
queryOperation.resultsLimit = 5
queryOperation.qualityOfService = .userInitiated
queryOperation.recordFetchedBlock = { record in
    self.array.append(record)
}
queryOperation.queryCompletionBlock = { cursor, error in
    if error != nil{
      cloudkitHelper.request(error: error!, viewController: self). //this line causes the crash

    }
    else{
        if cursor != nil {
            self.askAgain(cursor!)
        }
    }
    OperationQueue.main.addOperation {
        self.tableView.reloadData()
    }
}
Database.share.publicDB.add(queryOperation)
}

func askAgain(_ cursor: CKQueryOperation.Cursor) {
let queryOperation = CKQueryOperation(cursor: cursor)
queryOperation.resultsLimit = 5

queryOperation.recordFetchedBlock = {
    record in
    self.array.append(record)
}
queryOperation.queryCompletionBlock = { cursor, error in
    if error != nil{
        cloudkitHelper.request
    }
    else{
        if cursor != nil {
            self.askAgain(cursor!)
        }
    }
    OperationQueue.main.addOperation {
        self.tableView.reloadData()
    }
}
Database.share.publicDB.add(queryOperation)
}
}

class cloudkitHelper: ViewController{
static func request( error:Error, viewController:ViewController) {
    if let ckerror = error as? CKError {
        if ckerror.code == CKError.requestRateLimited {
            let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
            DispatchQueue.main.async {
                Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.getData), userInfo: nil, repeats: false)
            }
        }
        else if ckerror.code == CKError.zoneBusy {
            let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
            DispatchQueue.main.async {
                Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.getData), userInfo: nil, repeats: false)
            }
        }
        else if ckerror.code == CKError.limitExceeded {
            let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
            DispatchQueue.main.async {
                Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.getData), userInfo: nil, repeats: false)
            }
        }
}
  

2018-10-17 19:54:41.335517 + 0100 cloudkitApp [6011:1308502]   + [cloudkitApp.cloudkitHelper getData]:无法识别的选择器已发送给类0x103879c28 2018-10-17 19:54:41.407939 + 0100   cloudkitApp [6011:1308502] ***由于未捕获而终止应用程序   异常“ NSInvalidArgumentException”,原因:   '+ [cloudkitApp.cloudkitHelper getData]:无法识别的选择器已发送至   类别0x103879c28'

1 个答案:

答案 0 :(得分:1)

阅读错误消息。

它表示getData中没有选择器cloudkitHelper,这是事实。请根据命名约定将其命名为CloudkitHelper,并表示您正在调用 class 方法。

getData属于ViewController,(目标)self代表CloudkitHelper类。

Timer行更改为

Timer.scheduledTimer(timeInterval: retryInterval!, target: viewController, selector: #selector(getData), userInfo: nil, repeats: false)

ViewController和实例方法相比,extension和实例方法更合理。我删除了冗余代码,并使用了基于块的Timer API

extension ViewController {
    func request( error:Error) {
        if let ckerror = error as? CKError {
            switch ckerror.code {
            case .requestRateLimited, .zoneBusy, .limitExceeded:
                let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as! TimeInterval
                Timer.scheduledTimer(withTimeInterval: retryInterval, repeats: false) { _ in
                    DispatchQueue.main.async {
                        self.getData()
                    }
                }
            default: break
            }
        }
    }
}