我正在尝试使用API获取字符串数组(url)来填充数组。
数组的类型是:
var secImageUrls = [[String]](())
但是,我认为在填充数组时我遇到了某种时序问题,因为它每次看起来都不一样,即使它们都应该是相同的。
以下是代码:
var usersN = 0
for user in usersArray {
usersN++
let collab = user as! String
let r = i
let p = usersN
Alamofire.request(.GET, Constants.Path.rootUrl + "/api/users/?username=" +
collab + "&fields=image", headers: self.headers)
.responseJSON {response in
dispatch_async(dispatch_get_main_queue()){
let singleImgArray = response.result.value?.objectAtIndex(0) as! NSDictionary
let imageUrl = singleImgArray.objectForKey("image") as! String
self.collabsArray.append(imageUrl)
}
if p == usersArray.count {
//TO REMOVE???
dispatch_async(dispatch_get_main_queue()){
self.secImageUrls.append(self.collabsArray)
self.collabsArray = []
}
}
if r == self.jsonFeeds.count {
self.loadingStatus = "collabsPics"
self.tableView.reloadData()
}
}
}
编辑:这是现在的整个方法,使用调度组。但是,我仍然遇到数组问题(不要介意缺少else语句):
var i = 0
for feed in jsonFeeds {
i++
let feedType = feed["type"] as! Int
if feedType == 1 {
let usersArray : NSArray = feed["users"] as! NSArray
let group = dispatch_group_create()
for user in usersArray {
let collab = user as! String
let r = i
dispatch_group_enter(group)
Alamofire.request(.GET, Constants.Path.rootUrl + "/api/users/?username=" + collab + "&fields=image", headers: self.headers)
.responseJSON {response in
let singleImgArray = response.result.value?.objectAtIndex(0) as! NSDictionary
let imageUrl = singleImgArray.objectForKey("image") as! String
self.collabsArray.append(imageUrl)
dispatch_group_leave(group)
}
dispatch_group_notify(group, dispatch_get_main_queue()) {
self.secImageUrls.append(self.collabsArray)
self.collabsArray = []
if r == self.jsonFeeds.count {
self.loadingStatus = "collabsPics"
print(self.secImageUrls)
self.tableView.reloadData()
}
}
}
}
答案 0 :(得分:1)
你有点有时间问题。
按顺序启动一些请求 - 循环访问某些数据并为每个数据点执行异步请求。
请求完成后,您会将一些数据附加到数组中。到目前为止一切都很好。
但是没有人说请求必须按照他们开始的顺序完成。他们完成的顺序几乎是随机的。一个请求的计算成本可能更高,通过网络发送数据需要更长的时间等。
因此,您必须处理您的订单不具有确定性或为其实施某些逻辑/排序的事实。基于userIf或名称或其他东西 - 您的决定。
答案 1 :(得分:0)
正如我的评论和@ luk2302的回答所示,基本问题是您依靠网络操作以可靠的顺序完成。我的方法是创建一个预期结果数组,触发所有请求,将数组填充为响应,然后在完成后重新加载表。用dispatch_group包装它以进行协调,它看起来像
var collabsArray = Array<String?>(count: usersArray.count, repeatedValue: nil)
// Create a dispatch group for coordination
let group = dispatch_group_create()
for userIndex in 0..<usersArray.count {
let user = usersArray[userIndex]
let collab = user as! String
// "Enter" the group, basically increments the count of operations in the group
dispatch_group_enter(group)
Alamofire.request(.GET, Constants.Path.rootUrl + "/api/users/?username=" + collab + "&fields=image", headers: self.headers)
.responseJSON {response in
let singleImgArray = response.result.value?.objectAtIndex(0) as! NSDictionary
let imageUrl = singleImgArray.objectForKey("image") as! String
collabsArray[userIndex] = imageUrl
// "leave" the group, basically decrements the count of operations in the group
dispatch_group_leave(group)
}
}
// Schedule a block to execute when all the "enter" calls have been matched
// with "leave", ie., when all the network operations have finished, the block
// will be executed on the requested queue (in this case the main queue) so
// we don't have to futz with dispatch_async
dispatch_group_notify(group, dispatch_get_main_queue()) {
secImageUrls.append(collabsArray)
self.loadingStatus = "collabsPics"
self.tableView.reloadData()
}