我在理解块的确切运作方面遇到了一些问题。
for x in self.activerestaurantIDArray
{
let namelabel = x.0
self.activenameArray.append(namelabel)
let distancelabel = x.1
self.activedistanceArray.append(distancelabel)
let imageFile = x.2
imageFile.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
if error == nil {
let realimage = UIImage(data: imageData!)
self.activeimageArray.append(realimage!)
}
println(self.activenameArray)
println(self.activedistanceArray)
println(self.activeimageArray)
})
}
在上面的代码中,我将信息附加到元组中的数组(名为:activerestaurantIDArray
),以便我将获得名称,距离和图像的单独数组。至于图像,我只能从解析中检索PFFile,所以我必须将文件转换为UIImage。
但是,当我这样做时,仅当println()
在块(imageFile.getDataInBackgroundWithBlock
)内时,activeImageArray的附加才有效。
如果我在方框外的任何地方println(self.activeimageArray)
,那么数组将为零。我不确定为什么会发生这种情况,或者我应该如何确保附加值超出Block {}。任何帮助将不胜感激。
答案 0 :(得分:0)
Closures(也称为yes,blocks)是稍后可以调用的代码片段,它们本质上是函数。
您在imageFile.getDataInBackgroundWithBlock
中所做的是下载数据,下载数据时,imageFile.getDataInBackgroundWithBlock
会调用您的块,并向您传递内容它刚下载。
这样做是因为下载必须在一个单独的线程中进行。否则你的主线程会冻结,不仅会给用户带来麻烦,而且在5秒无响应之后,操作系统会终止你的应用。 getDataInBackgroundWithBlock
为下载操作生成一个不同的线程,然后通过调用您的块让您知道。这允许您下载任何没有"冻结"或者"悬挂"你的应用。
所以imageData
在块外部时为零,因为您在块完成下载操作之前尝试使用它。您的代码永远不会比下载操作慢,因此您必须使用该块来实现操作完成下载时要使用的代码,在这种情况下,设置imageData。
编辑添加,这不是Parse独有的。几乎任何可以冻结UI的框架都将执行这些操作并使用块实现通知。它仍然可以通过使用委托来通知,但是自从在Objective-C中引入了块之后,人们就一直在远离这种模式。