运行主线程的自定义方法

时间:2017-04-22 00:54:45

标签: ios multithreading swift3

class func loadData(
    onCompletition: @escaping ([LocationInfo])->Void){
    let workingQueue = DispatchQueue.global(qos:.utility)
    let completitionQueue = DispatchQueue.main
    workingQueue.sync {
        print("\n Data fetch started \n")
        let root = FIRDatabase.database().reference()
        let locationSummary = root.child("LocSummary")

        locationSummary.observeSingleEvent(of: .value,with: { (snapshot) in
            for item in snapshot.children{
                let locationInfo = LocationInfo(snapshot: item as! FIRDataSnapshot)
                FirebaseDataController.resultsArray.append(locationInfo)
            }
            completitionQueue.async {
                print("\n data fetch completed \n ")

                onCompletition(FirebaseDataController.resultsArray)
                print("After on completion method")
            }
        })
    }
}

我没有的问题是,每次我想访问结果数组中的数据时,我都必须通过这个函数完成处理程序。当我想使用表视图等时,我不能一直做这件事(我有一个单独的类来处理所有数据库交互和许多其他类来处理表视图交互)。

我的目标是在应用程序开始时运行此代码,可能是通过AppDelegate并有一个填充的数组,我可以随时调用我想要访问的数据。

要做到这一点,我想我需要在主线程上运行此代码。我尝试用主线程替换workingQueue但应用程序不断崩溃。

我能做些什么吗?

2 个答案:

答案 0 :(得分:0)

因为你想在主线程上调用该方法。

  • 首先删除与DispatchQueue相关的所有代码。
  • 然后使用loadData
  • 致电- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

答案 1 :(得分:0)

只有在启动应用程序时在主线程上同步调用此应用程序时,您的应用程序才会崩溃,因为您会导致死锁。如果您在AppDelegate的application:didFinishLaunching:方法中运行此函数,您应该能够安全地使用此实现:

class func loadData(onCompletition: @escaping ([LocationInfo])->Void){
    let completitionQueue = DispatchQueue.main   

    print("\n Data fetch started \n")
    let root = FIRDatabase.database().reference()
    let locationSummary = root.child("LocSummary")

    locationSummary.observeSingleEvent(of: .value,with: { (snapshot) in
        for item in snapshot.children{
            let locationInfo = LocationInfo(snapshot: item as! FIRDataSnapshot)
            FirebaseDataController.resultsArray.append(locationInfo)
        }
        completitionQueue.async {
            print("\n data fetch completed \n ")

            onCompletition(FirebaseDataController.resultsArray)
            print("After on completion method")
        }
    })
}

您猜测需要在主线程上执行此操作是错误的 - 没有理由这样做,事实上,您最终会遇到停滞不前的用户界面。获取数据,然后异步更新主线程上的用户界面。