我的应用程序发生了以下错误,我试图复制它,但我不能,所以谁能提供一些关于哪里出了问题的洞察力?
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 cloudkitApp6011 6011:1308502 +cloudkitApp.cloudkitHelper getData:未识别的选择器发送到类0x103879c28 2018-10-17 19:54:41.407939+0100 cloudkitApp6011 6011:1308502*由于“NSInvalidArgumentException”异常而终止应用程序,原因是:“+cloudkitApp.cloudkitHelper getData:未识别的选择器发送到类0x103879c28”
发布于 2018-10-17 22:05:17
请阅读的错误信息。
它说,在getData中没有选择器cloudkitHelper,这是真的。请根据命名约定将其命名为CloudkitHelper,并指示您正在调用类方法。
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
}
}
}
}https://stackoverflow.com/questions/52864205
复制相似问题