我从 Parse 下载了一个 PFFile 数组,我试图将它们转换为 NSData (imageDataArray) 数组,以便将它们保存到 Core Data 中。我现在遇到的唯一问题是 imageDataArray 的元素添加顺序错误,这意味着当我搜索 Core Data 时发现了错误的图像。
我发现这个问题(堆栈溢出问题 https://stackoverflow.com/questions/32163480/how-to-make-loop-wait-until-block-has-finished)这似乎解释了问题的原因是该块在不同时间完成任务,因此数组的顺序基于先完成的任务。然后他们建议使用 Grand Central Dispatch,但它都是用 Obj C 编写的,作为编码新手,我正在努力将其转换为 Swift 以用于我的项目。
您能否向我解释一下如何使用 GCD(或任何其他方法)以与原始 PFFile 数组相同的顺序创建 imageDataArray?
override func viewDidLoad() {
super.viewDidLoad()
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext
let dealsQuery = PFQuery(className: ("Deals"))
dealsQuery.orderByAscending("TrailId")
dealsQuery.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let objects = objects {
self.trailID.removeAll(keepCapacity: true)
self.trailStep.removeAll(keepCapacity: true)
self.dealNumber.removeAll(keepCapacity: true)
self.imageFile.removeAll(keepCapacity: true)
for object in objects {
self.trailID.append(object["TrailID"] as! Int)
self.trailStep.append(object["TrailStep"] as! Int)
self.dealNumber.append(object["dealNumber"] as! Int)
self.imageFile.append(object["dealImage"] as! PFFile!)
}
}
var counter = 0
for file in self.imageFile {
let dealImage = file
dealImage.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
if error == nil {
weak var aBlockSelf = self
let image = UIImage(data: imageData!)
aBlockSelf!.imageDataArray.append(imageData!)
self.imagesArray.append(image!)
if counter == self.trailStep.count - 1{
print(self.trailID.count)
print(self.trailStep.count)
print(self.dealNumber.count)
print(self.imageDataArray.count)
print(self.trailStep[0])
print(self.dealNumber[0])
let image = UIImage(data: self.imageDataArray[0])
self.imageView.image = image
} else {counter++}
}
})
很抱歉在这里发布我的所有代码。我想问题在底部,但作为初学者,我认为我可能在其他地方犯了错误,所以我认为最好将其全部发布。
非常感谢你的帮助。
Update 1
我尝试添加一个预填充数组(imageArray)并尝试将数据放入其中,但在搜索 TrailStep 和 dealNumber 时它仍然是随机的。我缺少什么?谢谢
var i = 0
var imageArray = [NSData!](count: self.trailStep.count, repeatedValue: nil)
for file in self.imageFile {
let dealImage = file
dealImage.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
if error == nil {
//weak var aBlockSelf = self
let image = UIImage(data: imageData!)
imageArray[i] = imageData!
if i == self.trailStep.count - 1{
print(self.trailID.count)
print(self.trailStep.count)
print(self.dealNumber.count)
print(self.imageDataArray.count)
print(self.trailStep[3])
print(self.dealNumber[3])
let image = UIImage(data: imageArray[3])
self.imageView.image = image
} else {i++}
}
})
Update 2
我一直在研究和尝试 GCD 和串行调度,这就是我目前所处的位置。我认为我对 GCD 的看法过于简单化,但无法完全理解它是如何工作的以及它如何让我的块以正确的顺序添加到 imageDataArray 中。
var counter = 0
var imageArray = [NSData!](count: self.trailStep.count, repeatedValue: nil)
weak var aBlockSelf = self
var serialQueue = dispatch_queue_create("serial", nil)
for file in self.imageFile {
let dealImage = file
var imageDataArray = [NSData!](count: self.imageFile.count, repeatedValue: nil)
dispatch_async(serialQueue, { () -> Void in
dealImage.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
if error == nil {
let imageIndex = self.imageFile.indexOf(file)
let image = UIImage(data: imageData!)
imageDataArray.insert(imageData!, atIndex: imageIndex!)
if counter == self.trailStep.count - 1{
print(self.trailID.count)
print(self.trailStep.count)
print(self.dealNumber.count)
print(imageDataArray.count)
print(self.trailStep[0])
print(self.dealNumber[0])
let image = UIImage(data: imageDataArray[4])
self.imageView.image = image
} else {counter++}
return
}
})
此代码在“let image = UIImage(data: imageDataArray[4])”行上返回错误“展开可选值时意外发现 nil”。这与我在尝试实现 GCD 之前遇到的错误相同......