необработанное исключение NSInvalidArgumentException при обработке ошибок облачного набора - PullRequest
0 голосов
/ 18 октября 2018

Мое приложение упало со следующей ошибкой, я пытаюсь воспроизвести его, но не могу, поэтому кто-нибудь может дать некоторое представление о том, что происходит не так?

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-1719: 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 голосов
/ 18 октября 2018

Пожалуйста, прочитайте сообщение об ошибке.

В нем говорится, что в cloudkitHelper нет селектора getData, что соответствует действительности.Назовите его 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
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...