访问闭包Swift3之外的变量
Posted
技术标签:
【中文标题】访问闭包Swift3之外的变量【英文标题】:Accessing a variable outside closure Swift3 【发布时间】:2017-04-21 00:47:34 【问题描述】:我已经在 ViewController 类的开头声明了 requestPostArray。我正在尝试从数据库“Request Posts”中填充 requestPostArray,然后从 requestPostArray 中填充 tableView。但是,当我打印它的大小时,它显示为 0。任何帮助将不胜感激。
此外,下面的整个 else 语句都在另一个闭包中。
else
ref.child("Request Posts").observe(.value, with: (snapshot) in
let count = Int(snapshot.childrenCount)
// Request Post database is empty
if count == 0
cell.nameLabel.text = "No requests so far."
cell.userNameLabel.isHidden = true
cell.numberOfRequestsLabel.isHidden = true
// Request Post data is populated
else
var requestPostArray: [RequestPost]? = []
self.ref.child("Request Posts").observe(.value, with: (snapshot) in
if let result = snapshot.children.allObjects as? [FIRDataSnapshot]
for child in result
let post = RequestPost(snapshot: child)
requestPostArray?.append(post)
else
print("No Result")
)
print("RequestPostArray size = \(requestPostArray?.count ?? 90)")
cell.nameLabel.text = self.requestPostArray?[indexPath.row].name
cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name
cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name
)
【问题讨论】:
【参考方案1】:observe
块是异步的。在 requestPostArray?.append(post)
行修改之前,您正在阅读 requestPostArray
。
如果没有更多上下文,很难知道您希望如何在此 cell
对象上填充值,但如果您需要“请求帖子”,则必须等到您能够获得它们。
【讨论】:
谢谢乔纳!我做“请求帖子”数据库。我创建了一个名为“RequestPost”的自定义类型对象,我想将数据库中的所有子对象存储到一个名为 requestPostArray 的 RequestPost 数组中,其成员将填充表格单元格。我究竟如何“等到你能够获得它们”。是否有一个特定的函数只在块完成执行后触发? 您似乎正试图在表视图数据源的cellForRowAtIndexPath
内进行异步查询。这是行不通的,因为cellForRowAtIndexPath
需要立即得到结果并且不会等待您的查询运行。而是考虑如何设计FUITableViewDataSource
(github.com/firebase/FirebaseUI-ios/tree/master/…) 来解决这个问题。【参考方案2】:
这是应该发生的,因为观察函数是异步的,而您的其余代码是同步的,此外,如果您从 requestPostArray?
中删除可选的 unwrap,您将得到一个 nil 异常,因为异步任务需要时间来执行所以编译器将在它之前执行 snyc 任务。
基本上你要做的就是以下
else
ref.child("Request Posts").observe(.value, with: (snapshot) in
let count = Int(snapshot.childrenCount)
// Request Post database is empty
if count == 0
cell.nameLabel.text = "No requests so far."
cell.userNameLabel.isHidden = true
cell.numberOfRequestsLabel.isHidden = true
// Request Post data is populated
else
var requestPostArray: [RequestPost]? = []
self.ref.child("Request Posts").observe(.value, with: (snapshot) in
if let result = snapshot.children.allObjects as? [FIRDataSnapshot]
for child in result
let post = RequestPost(snapshot: child)
requestPostArray?.append(post)
else
print("No Result")
print("RequestPostArray size = \(requestPostArray?.count ?? 90)")
cell.nameLabel.text = self.requestPostArray?[indexPath.row].name
cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name
cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name
)
)
另一个建议是考虑使用单例,这样您就可以获得对象的重用,并且您不会像现在那样以相同的方法多次调用数据库。
【讨论】:
谢谢Achref!我对 Swift 比较陌生,所以我不太确定单例是什么。您能否简要地告诉我它是什么或指向我可以找到更多信息的链接?谢谢 请看这里***.com/a/43513805/4442592,我包含了一个完整的例子,更多细节我想邀请你阅读这个很棒的教程:raywenderlich.com/86477/… 我的回答有帮助吗? 是的,您的回答很有帮助。它确实有效,但事实证明我必须手动设置表的 numberOfRowsInSection() 才能显示正确的行数。我目前正在尝试将数据库中的帖子数量存储在一个变量中,然后在 numberOfRowsInSection() 函数中返回它。 这是另一个问题,请将此问题标记为已解决并提出一个新问题。以上是关于访问闭包Swift3之外的变量的主要内容,如果未能解决你的问题,请参考以下文章