如何在 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")
    }

我能理解的是,你想让循环等待,直到在那个特定的交互编号中没有获取数据。如果是这种情况,那么您应该寻找同步操作。就像在操作完成之前不要让控制传递给下一次迭代一样。但这是一种不好的做法,会使您的应用行为无响应。

我想说的是在异步线上工作并创建一个块或闭包,然后将您的代码放在接收数据时预期执行的代码中,并将代码放在不依赖于数据的块之外。无论如何,块都会捕获环境,在这种情况下,您不必担心控制被通过。