Ios 从API填充数组时可能出现计时问题
我试图用从API获得的字符串数组(URL)填充数组 阵列的类型为:Ios 从API填充数组时可能出现计时问题,ios,swift,alamofire,Ios,Swift,Alamofire,我试图用从API获得的字符串数组(URL)填充数组 阵列的类型为: var secImageUrls = [[String]](()) 然而,我认为我在填充数组时遇到了一些计时问题,因为它每次看起来都不一样,尽管它应该是相同的 代码如下: var usersN = 0 for user in usersArray { usersN++ let collab = user as! String let r = i let p = usersN Ala
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语句):
你有点时间问题
您按顺序启动几个请求—循环一些数据,并对每个数据点执行异步请求
一旦请求完成,就向数组中添加一些数据。到目前为止还不错
但是没有人说请求必须按照开始的顺序完成。它们完成的顺序几乎是随机的。一个请求的计算成本可能更高,通过网络发送数据所需的时间更长等等
因此,您要么必须处理您的顺序不确定的事实,要么为其实现一些逻辑/顺序。基于userIf或名称或其他什么-您的决定。正如我的评论和@luk2302的回答所表明的,基本问题是您依赖网络操作以可靠的顺序完成。我的方法是创建一个包含预期结果的数组,激发所有请求,将数组填充为响应,然后在完成后重新加载表。用一个调度组来进行协调,它看起来像
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()
}
var collabsArray=Array(计数:usersArray.count,repeatedValue:nil)
//创建调度组以进行协调
let group=dispatch\u group\u create()
对于0中的userIndex..由于执行网络操作的时间不确定,因此附加到secImageUrls
的URL也将不确定。同样不清楚的是,为什么要分配到主队列(以及为什么要分配两次而不是一次),然后一件可能应该被分配到主队列的事情(self.tableView.reloadData()
)不是…在数组初始化中有冗余的()
-[[String]](
)。还有,为什么要在异步块中处理响应?@mixel以何种方式处理()
冗余?没有它,代码就不能工作。@luk2302我的意思是[[String]]()
而不是[[String]](())
也可以工作。@mixel啊,我明白了,对不起!谢谢你的回答!你能给我解释一下这个例子中的队列逻辑吗?真的,对于类似的事情,我会重构工作流程,以便表格单元格加载图像并根据需要重新显示自己,以便单个单元格在数据可用时刷新,但这是一个完全不同的问题和答案。你是在问关于dispatch_group_*的问题吗?这可能是“类似于”的问题的一部分,你实际上想实现什么还不太清楚:)再看一遍,我可能在你使用collab的地方使用了secImageUrls?在这种情况下,您可以使用collab替换所有secimageURL,然后在_notify调用中附加到secimageURL。是的,完全正确。无论如何,我正在尝试构建一个超级数组(secImageUrls),用于在表视图的每个单元格上存储多个图像的URL。@dpstart我说过调度组吗?不因为我不喜欢它们,所以必须按照我说的对数组进行排序。
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()
}