所以我正在进行后台提取,之后我想更新UI。后台获取本身(数据库)有效,但是当我想更新UI时,我遇到了崩溃unexpectedly found nil while unwrapping an Optional value
根据我的xCode self.newestPublicationsCollectionView.reloadData()
是updateCollections()函数中发生崩溃的地方。
func updateCollections() {
// get latest data from Database
latestPublications = getNewestPublications()
self.newestPublicationsCollectionView.reloadData()
self.newestPublicationsCollectionView.layoutIfNeeded()
// fix wrong content height
self.newestPublicationsCollectionViewHeight.constant = self.newestPublicationsCollectionView.collectionViewLayout.collectionViewContentSize().height
}
AppDelegate中的其他代码:
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
let fetchViewController = PublicationOverviewController()
fetchViewController.fetch {
dispatch_async(dispatch_get_main_queue()) {
fetchViewController.updateCollections()
}
completionHandler(.NewData)
}
}
我的PublicationOverviewController中的.fetch
func fetch(completion: () -> Void) {
PublicationFetcher.shared.fetchAllPublications()
completion()
}
我认为崩溃是因为我需要主线程上的UI,但这没有帮助。任何输入都会很好。
详情:
在我的PublicationFetcher.shared.fetchAllPublications()中,我执行以下操作:
dispatch_async(dispatch_get_main_queue()) { () -> Void in NSNotificationCenter.defaultCenter().postNotificationName("RELOAD_NOTIFICATION", object: nil) }
根据重新加载通知我执行了updateCollections()
DispatchQueue.global(attributes: .qosBackground).async {
print("This is run on the background queue")
DispatchQueue.main.async {
print("This is run on the main queue, after the previous code in outer block")
}
}
答案 0 :(得分:0)
尝试在启动UI操作之前为应用程序提供30秒的超时时间,这对您的后台网络连接很有帮助:
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
let fetchViewController = PublicationOverviewController()
fetchViewController.fetch {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (Int64)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue()) {
<#code to be executed after a specified delay#>
fetchViewController.updateCollections()
completionHandler(.NewData)
}
}
您也可以使用此功能:
func dispatchDelay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
将其称为此示例:
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
let fetchViewController = PublicationOverviewController()
fetchViewController.fetch {
dispatchDelay(25) { // put what you want
// this is main-thread queue
fetchViewController.updateCollections()
completionHandler(.NewData)
}
}
}
答案 1 :(得分:0)
不要再次初始化PublicationOverviewController()
,因为它会为您提供该视图的新实例,而您不会获得引用的collectionView
。此外,在viewDidLoad:
接听电话之前,您将获得所有UI控件。
示例:
let *controller : PublicationOverviewController = PublicationOverviewController()
// controller.collectionView will be nil here because view hasn't loaded yet
您可以做什么在applicationDidBecomeActive:
方法中发布通知,在observe
中PublicationOverviewController
发布通知,然后在相应方法中重新加载collectionView
。