异步调用完成后如何启动另一个任务

时间:2016-06-10 09:10:31

标签: ios swift asynchronous firebase grand-central-dispatch

目前,我正在使用firebase。我使用firebase异步调用observeEventType填充我的表。但是现在我也在使用BTNavigationDropdownMenu,我需要从数据库中填充我的标题。由于firebase查询是异步的,我怎么能这样做只有当它完成后才会被BTNavigationDropdownMenu解雇?

这是我在viewDidAppear调用从firebase

检索数据的调用
_ = dataRef.observeSingleEventOfType(.Value, withBlock: { (snapshotOne) in

        self.titleList.insert("\(snapshotOne.key)", atIndex: 0)
})

这应该在检索数据后触发

let menuView = BTNavigationDropdownMenu(navigationController: self.navigationController, title: titleList.first!, items: titleList)

self.navigationItem.titleView = menuView

我得到的错误是unwrapping a nil in titleList,当然情况就是如此,因为titleList还没有被firebase填充。

我尝试了两件失败的事情。首先,我将BTNavigationDropdownMenu代码放在我的firebase调用中。但是,随着代码被调用,这给了我一个记忆警告。

其次我尝试使用dispatch_asyncserial queue,但由于我在异步代码中排队异步代码,因此无效,这意味着我的队列触发了firebase异步代码并移至我的{{1在firebase响应之前。

2 个答案:

答案 0 :(得分:0)

只需在value event

的异步完成闭包内设置titleView
 dataRef.observeSingleEventOfType(.Value, withBlock: { (snapshotOne) in

        self.titleList.insert("\(snapshotOne.key)", atIndex: 0)
        let menuView = BTNavigationDropdownMenu(navigationController: self.navigationController, title: titleList.first!, items: titleList)

        self.navigationItem.titleView = menuView
})

答案 1 :(得分:0)

我认为你最好的选择是将UINavigationController子类化为解决你的记忆问题。 menuView已在UIViewController内初始化,但随后添加为subview navigationController。因此,当ViewController应该解除分配时,menuView尚未解除分配,因为它仍在navigationController上,同时仍然引用UIViewController所以UIViewController也不能dealloc。它不在navigationStack上,但仍然存在于内存中创建您的问题。这是一个快速的子类。

class MyNavController : UINavigationController {
   var menuView : BTNavigationDropdownMenu = BTNavigationDropdownMenu()

   override func viewDidLoad() {
      super.viewDidLoad()

      //Do additional setup like adding to superView or whatever else you need. 
      titleView = menuView
   }
}

在firebase完成块中

_ = dataRef.observeSingleEventOfType(.Value, withBlock: { (snapshotOne) in
        //Individually set all of the values of your menuView here.
       if let navVC = self.navigationController as? MyNavController {
           navVC.menuView.title = titleList.first 
       }

})

这里的关键是menuView现在只有对navBar的引用,因此将使用navBar释放自己,你的VC现在可以在其上取消分配,因为menuView不再有对它的引用。因此,虽然创建弱引用可以解决您的内存问题,但如果navController生成navController

,则{{1}}的生命周期更有意义。