我是Swift和异步代码的新手,所以告诉我这是否可行。基本上我想:


开启应用程式
触发读取CloudKit记录
读取完成后,UILabel将显示检索到的记录数


显然这本身并没有用,但是作为一个原则,它将帮助我理解异步代码操作以及如何在完成操作时触发操作。

// In ViewController Swift file:

class ViewController: UIViewController{

    override func viewDidLoad() {
        super.viewDidLoad()
        readDatabase()
    }
    @IBOutlet weak var myLabel: UILabel!
}

let VC=ViewController()


//In Another Swift file:

func readDatabase() {
    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: "myRecord", predicate: predicate)
    let container = CKContainer.default()
    let privateDB = container.privateCloudDatabase

    privateDB.perform(query, inZoneWith:nil) { (allRecs, err) in
        VC.myLabel.text = ("\(allRecs?.count) records retreived")

    /*
    ERROR OCCURS IN LINE ABOVE:
       CONSOLE: fatal error: unexpectedly found nil while unwrapping an Optional value
       BY CODE LINE: Thread 8:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    */

    }
}


我可以在viewDidLoad函数中设置文本字段,为什么不从该函数中调用的函数中设置呢?

我尝试过的其他几件事:


使用异步调度将其放在线程1上
在ViewController类中使用didSet设置文本来实现var,将var设置为privateDB.perform代码中所需的值以触发更改


这些都产生与上述相同的问题。

是的,我知道.perform中没有任何错误处理,是的,有记录。如果在加载视图几秒钟后手动将UILabel文本的设置触发为记录计数,则可以正常工作。

所以问题是...
如何使用数据库的完成读取作为触发器来将记录的属性加载到视图?

谢谢

最佳答案

问题出在这行:let VC=ViewController()。在这里,您实例化了ViewController类的新实例,并尝试在该新创建的实例上设置标签。但是,您需要在当前显示的viewController实例上设置标签。

只需将此行VC.myLabel.text = ("\(allRecs?.count) records retreived")更改为self.myLabel.text = ("\(allRecs?.count) records retreived"),它应该可以正常工作。

关于ios - 在Swift中完成CloudKit异步操作时设置UILabel文本,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44418155/

10-11 22:30
查看更多