【发布时间】:2017-11-09 03:09:58
【问题描述】:
我是 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 类中实现一个 var with,使用一个设置文本的 didSet,在 privateDB.perform 代码中将 var 设置为所需的值以触发更改
这些都会产生与上述相同的问题。
是的,我知道 .perform 中没有任何错误处理,是的,有记录。如果我在视图加载几秒钟后手动触发将 UILabel 文本设置为记录计数,它可以正常工作。
所以问题是…… 如何使用数据库读取完成作为触发器将记录的属性加载到视图中?
谢谢
编辑
这里实际发生的是 VC 是全局创建的,但从未呈现 - 因为从未调用过 loadView,所以 myLabel 不存在,并且作为强制解包的属性,当它发生时导致崩溃被引用了
【问题讨论】: