iOS Swift:查询完成后将数据传递给其他 VC 的最佳方式
Posted
技术标签:
【中文标题】iOS Swift:查询完成后将数据传递给其他 VC 的最佳方式【英文标题】:iOS Swift: best way to pass data to other VCs after query is completed 【发布时间】:2016-11-20 11:36:06 【问题描述】:上下文: ios 应用采用 Swift 3 编写,由 Firebase 3.0 提供支持
挑战:在我的应用中,用户的 currentScore 存储在 Firebase 上。该用户可以从多个 ViewController 完成/取消完成任务(这将增加/减少其 currentScore)。
应用架构概览:
ProfileVC - 我从 Firebase 获取 currentUser 的数据并显示 currentScore。
⎿ 容器视图
⎿ CollectionViewController - users can update their score from here ⎿ DetailsVC - (when users tap on a collectionView cell) - again users can update their score from here.
问题:我需要将 currentScore 传递给可以更新分数的 VC。我考虑过在级联中使用 prepare(forSegue) 但这不起作用,因为它在 ProfileVC 上的查询完成之前通过了“nil”。
我想避免使用全局变量,因为有人告诉我这是不好的做法。
任何想法将不胜感激。
【问题讨论】:
如果使用得当且谨慎使用,全局变量是不错的做法。 Apple 在开发者文档中介绍了它们的使用。在您的情况下,如果应用程序范围内需要数据,它可能是合适的。你提到prepareForSegue ..这是一个传递变量的好地方,不清楚为什么它会传递零。每次更改视图时,您是否都在进行 Firebase 查询?如果是这样,那会增加很多不必要的开销。如果需要,请在 Firebase 从查询返回后,在闭包内启动 segue。 【参考方案1】:为什么不创建一个函数,在你做任何其他事情之前先提取所有数据。
所以在 ViewDidLoad 调用中...
pullFirebaseDataASYNC()
函数如下所示...
typealias CompletionHandler = (_ success: Bool) -> Void
func pullFirebaseDataASYNC()
self.pullFirebaseDataFunction() (success) -> Void in
if success
// Perform all other functions and carry on as normal...
Firebase 函数可能看起来像...
func pullFirebaseDataFunction(completionHandler: @escaping CompletionHandler)
let refUserData = DBProvider.instance.userDataRef
refUserData.observeSingleEvent(of: .value, with: snapshot in
if let dictionary = snapshot.value as? [String: AnyObject]
self.userCurrentScore = dictionary["UserScore"] as! Int
completionHandler(true)
)
然后,当您将信息转移到... 在 ProfileVC 中 创建 2 个属性
var containerVC: ContainerVC!
var userCurrentScore = Int()
在 ProfileVC 中包含以下函数...
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "ProfileToContainerSegue"
let destination = segue.destination as! ContainerVC
containerVC = destination
containerVC.userCurrentScore = userCurrentScore
在 ContainerVC 中创建一个属性
var userCurrentScore = Int()
改进的方法可能是一条错误消息,以确保在用户可以继续之前从 Firebase 提取所有信息... 然后可以通过与上述相同的方式来分隔信息。
【讨论】:
【参考方案2】:尝试实例化,首先将导航控制器嵌入到您的第一个故事板中,然后将 storyboardID 提供给您要展示的 VC。
let feedVCScene = self.navigationController?.storyboard?.instantiateViewController(withIdentifier: "ViewControllerVC_ID") as! ViewController
feedVCScene.scoreToChange = current_Score // scoreToChange is your local variable in the class
// current_Score is the current score of the user.
self.navigationController?.pushViewController(feedVCScene, animated: true)
PS:- 实例化比 模态 segue 故事板传输更健康的原因,它几乎消除了您在来回导航时的内存泄漏,也避免VC的堆叠。
【讨论】:
嘿德拉威人,感谢您的回答。我已经为这个特定部分添加了我的故事板的屏幕截图。我使用第三方库创建了一个可滑动的页面菜单来过滤我的 collectionView。所以基本上一旦用户加载其profileScreen。 profile 元素和 collectionView 同时加载,这就是 segue 过早触发的原因(与我的查询相比)。我不确定我是否理解实例化的含义。这仍然与我添加的其他详细信息相关吗?提前致谢。 是的,它仍然相关。以上是关于iOS Swift:查询完成后将数据传递给其他 VC 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章
Swift segue 不会将数据传递给旧的 ViewController