如何在 swift 中用同步编码嵌套循环?
How to code Nested Loop with synchronous in swift?
在我的项目中,我调用了 getMain() 并且它有嵌套循环。该循环调用 setUp()。我的问题是 setUp() 完成之前,上层循环退出。
首先调用getMian():
func getMain(){
let entityDescription = NSFetchRequest<NSFetchRequestResult>(entityName: "MainThemeHome")
do{
let results = try context.fetch(entityDescription)
if(results.count) > 0 {
sections.removeAll()
debugPrint(results.count)
outer_count = results.count
for i in 0 ..< (results.count){
let match = results[i] as! NSManagedObject
let associated_url = match.value(forKey: "main_associated_url") as! String
let name = match.value(forKey: "main_name") as! String
//call function
self.setUpViews(associated_url: associated_url, main_name: name, i: i )
self.myGroup.leave()
}
}else{
}
}catch{}
}
下面是循环调用setUp(),
private func setUp(associated_url : String , main_name: String,i : Int) {
if Reachability().isInternetAvailable() == true {
self.rest.auth(auth: self.prefs.value(forKey: "access_token") as! String!)
self.rest.get(url: StringResource().mainURL + associated_url , parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in
self.assetsTable.removeAll()
if(status == 200){
let data = result["data"] as! NSArray
for item in 0…data.count - 1 {
let themes : AnyObject = data[item] as AnyObject
let created = themes["created"] as! String
let assets_id = themes["id"] as! Int
let name = themes["name"] as! String
var poster_img_url = themes["poster_image_url"] as! String
let provider_id = themes["provider_id"] as! Int
poster_img_url = StringResource().posterURL + poster_img_url
self.assetsTable.append(AssetsTableItem(created: created, assets_id: assets_id, name: name, poster_image_url: poster_img_url , provider_id: provider_id))
}
}
self.sections.append(SectionsHome(package_name: main_name, package_url: associated_url,i: i,packageTable: self.assetsTable))
self.inner_count = self.sections.count
}else{
}
})
}
}
如何控制setUp()完全结束,循环会增加计数并退出。如何解决这个问题呢。请帮忙。
您需要在 setUp 函数中使用闭包,这样当 setUp 完成时您将获得回调
private func setUp(associated_url : String , main_name: String,i : Int, ,sucess:((Void) -> Void)?,failure:((Void?) -> Void)?) {
if Reachability().isInternetAvailable() == true {
self.rest.auth(auth: self.prefs.value(forKey: "access_token") as! String!)
self.rest.get(url: StringResource().mainURL + associated_url , parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in
self.assetsTable.removeAll()
if(status == 200){
let data = result["data"] as! NSArray
for item in 0…data.count - 1 {
let themes : AnyObject = data[item] as AnyObject
let created = themes["created"] as! String
let assets_id = themes["id"] as! Int
let name = themes["name"] as! String
var poster_img_url = themes["poster_image_url"] as! String
let provider_id = themes["provider_id"] as! Int
poster_img_url = StringResource().posterURL + poster_img_url
self.assetsTable.append(AssetsTableItem(created: created, assets_id: assets_id, name: name, poster_image_url: poster_img_url , provider_id: provider_id))
}
}
self.sections.append(SectionsHome(package_name: main_name, package_url: associated_url,i: i,packageTable: self.assetsTable))
self.inner_count = self.sections.count
sucess!()
}else{
failure!()
}
})
}
}
并将调用函数的方式更改为
self.setUp(associated_url: associated_url, main_name: name, i: i, sucess: { () in
debugPrint("SUCCESS")
}) { () in
debugPrint("FAILURE")
}
我能理解的是,你想让循环等待,直到在那个特定的交互编号中没有获取数据。如果是这种情况,那么您应该寻找同步操作。就像在操作完成之前不要让控制传递给下一次迭代一样。但这是一种不好的做法,会使您的应用行为无响应。
我想说的是在异步线上工作并创建一个块或闭包,然后将您的代码放在接收数据时预期执行的代码中,并将代码放在不依赖于数据的块之外。无论如何,块都会捕获环境,在这种情况下,您不必担心控制被通过。
在我的项目中,我调用了 getMain() 并且它有嵌套循环。该循环调用 setUp()。我的问题是 setUp() 完成之前,上层循环退出。
首先调用getMian():
func getMain(){
let entityDescription = NSFetchRequest<NSFetchRequestResult>(entityName: "MainThemeHome")
do{
let results = try context.fetch(entityDescription)
if(results.count) > 0 {
sections.removeAll()
debugPrint(results.count)
outer_count = results.count
for i in 0 ..< (results.count){
let match = results[i] as! NSManagedObject
let associated_url = match.value(forKey: "main_associated_url") as! String
let name = match.value(forKey: "main_name") as! String
//call function
self.setUpViews(associated_url: associated_url, main_name: name, i: i )
self.myGroup.leave()
}
}else{
}
}catch{}
}
下面是循环调用setUp(),
private func setUp(associated_url : String , main_name: String,i : Int) {
if Reachability().isInternetAvailable() == true {
self.rest.auth(auth: self.prefs.value(forKey: "access_token") as! String!)
self.rest.get(url: StringResource().mainURL + associated_url , parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in
self.assetsTable.removeAll()
if(status == 200){
let data = result["data"] as! NSArray
for item in 0…data.count - 1 {
let themes : AnyObject = data[item] as AnyObject
let created = themes["created"] as! String
let assets_id = themes["id"] as! Int
let name = themes["name"] as! String
var poster_img_url = themes["poster_image_url"] as! String
let provider_id = themes["provider_id"] as! Int
poster_img_url = StringResource().posterURL + poster_img_url
self.assetsTable.append(AssetsTableItem(created: created, assets_id: assets_id, name: name, poster_image_url: poster_img_url , provider_id: provider_id))
}
}
self.sections.append(SectionsHome(package_name: main_name, package_url: associated_url,i: i,packageTable: self.assetsTable))
self.inner_count = self.sections.count
}else{
}
})
}
}
如何控制setUp()完全结束,循环会增加计数并退出。如何解决这个问题呢。请帮忙。
您需要在 setUp 函数中使用闭包,这样当 setUp 完成时您将获得回调
private func setUp(associated_url : String , main_name: String,i : Int, ,sucess:((Void) -> Void)?,failure:((Void?) -> Void)?) {
if Reachability().isInternetAvailable() == true {
self.rest.auth(auth: self.prefs.value(forKey: "access_token") as! String!)
self.rest.get(url: StringResource().mainURL + associated_url , parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in
self.assetsTable.removeAll()
if(status == 200){
let data = result["data"] as! NSArray
for item in 0…data.count - 1 {
let themes : AnyObject = data[item] as AnyObject
let created = themes["created"] as! String
let assets_id = themes["id"] as! Int
let name = themes["name"] as! String
var poster_img_url = themes["poster_image_url"] as! String
let provider_id = themes["provider_id"] as! Int
poster_img_url = StringResource().posterURL + poster_img_url
self.assetsTable.append(AssetsTableItem(created: created, assets_id: assets_id, name: name, poster_image_url: poster_img_url , provider_id: provider_id))
}
}
self.sections.append(SectionsHome(package_name: main_name, package_url: associated_url,i: i,packageTable: self.assetsTable))
self.inner_count = self.sections.count
sucess!()
}else{
failure!()
}
})
}
}
并将调用函数的方式更改为
self.setUp(associated_url: associated_url, main_name: name, i: i, sucess: { () in
debugPrint("SUCCESS")
}) { () in
debugPrint("FAILURE")
}
我能理解的是,你想让循环等待,直到在那个特定的交互编号中没有获取数据。如果是这种情况,那么您应该寻找同步操作。就像在操作完成之前不要让控制传递给下一次迭代一样。但这是一种不好的做法,会使您的应用行为无响应。
我想说的是在异步线上工作并创建一个块或闭包,然后将您的代码放在接收数据时预期执行的代码中,并将代码放在不依赖于数据的块之外。无论如何,块都会捕获环境,在这种情况下,您不必担心控制被通过。