Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/121.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 函数不从闭包返回值_Ios_Swift_Closures - Fatal编程技术网

Ios 函数不从闭包返回值

Ios 函数不从闭包返回值,ios,swift,closures,Ios,Swift,Closures,我需要从包含闭包的函数返回一个值 我研究了从闭包返回值的问题,发现我应该使用“完成处理程序”来获得我想要的结果 我在这里看到了一些帖子和文章解释了这一点,但无法应用,因为我没有发现任何与我的问题相匹配的东西 class ViewController: UIViewController { let urls = URLs() override func viewDidLoad() { super.viewDidLoad() var league

我需要从包含闭包的函数返回一个值

我研究了从闭包返回值的问题,发现我应该使用“完成处理程序”来获得我想要的结果

我在这里看到了一些帖子和文章解释了这一点,但无法应用,因为我没有发现任何与我的问题相匹配的东西

class ViewController: UIViewController {

    let urls = URLs()

    override func viewDidLoad() {
        super.viewDidLoad()

        var leagueId = getLeagueId(country: "brazil", season: "2019")
        print(leagueId) //PRINTING 0

    }

    func getLeagueId (country: String, season: String) -> Int {

        let headers = Headers().getHeaders()
        var leagueId = 0
        let url = urls.getLeagueUrlByCountryAndSeason(country: country, season: season)


        Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON {
            response in
            if response.result.isSuccess {
                let leagueJSON: JSON = JSON(response.result.value!)
                leagueId = (leagueJSON["api"]["leagues"][0]["league_id"].intValue)

            }
            else {
                print("error")
            }
        }
           return leagueId
    }
}
返回的值始终为0,因为闭包值未传递给函数本身


非常感谢

这是您应该如何实现completionBLock的

func getLeagueId (country: String, season: String, completionBlock:((_ id: String, _ error: Error?) -> Void)?) {

            let headers = Headers().getHeaders()
            var leagueId = 0
            let url = urls.getLeagueUrlByCountryAndSeason(country: country, season: season)


            Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON {
                response in
                if response.result.isSuccess {
                    let leagueJSON: JSON = JSON(response.result.value!)
                    if let leagueId = (leagueJSON["api"]["leagues"][0]["league_id"].intValue){
                      completionBlock?(leagueId,nil) 
                   }else {
                        completionBlock?(nil,nil) // PASS YOUR ERROR
                     }
                }
                else {
                      completionBlock?(nil,nil) // PASS YOUR ERROR
                }
            }
        }

您需要从函数返回值

func getLeagueId (country: String, season: String)->Int
否则您需要使用完成处理程序

func getLeagueId (country: String, season: String,success:@escaping (leagueId: Int) -> Void) {

    let headers = Headers().getHeaders()
    var leagueId = 0
    let url = urls.getLeagueUrlByCountryAndSeason(country: country, season: season)


    Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON {
        response in
        if response.result.isSuccess {
            let leagueJSON: JSON = JSON(response.result.value!)
            leagueId = (leagueJSON["api"]["leagues"][0]["league_id"].intValue)
            success(leagueId)

        }
        else {
            print("error")
        }
    }
}
然后在代码中使用它:

  getLeagueId(country: "brazil", season: "2019",success: { (leagueId) in
            print(leagueId)
self.leagueId = leagueId
        })

所以出现这个问题的原因是因为AlamoFire.request是异步的。异步与同步有一个很好的解释,但基本上,当您异步执行某个任务时,编译器不会等待任务完成后再继续执行下一个任务,而是会立即执行下一个任务

因此,在您的情况下,执行AlamoFire.request,当它运行时,立即运行块后的下一行,即返回leagueId的行,该行显然仍然等于零,因为AlamoFire.request任务函数尚未完成

这就是为什么需要使用闭包。闭包将允许您在AlamoFire.request或任何其他异步任务完成运行后返回该值。上面Manav的回答向您展示了在Swift中执行此操作的正确方法。我只是想帮你理解为什么这是必要的

希望这能有所帮助

编辑:

马纳夫上面的回答实际上部分是正确的。以下是您如何创建它,以便以正确的方式重用该值

var myLeagueId = 0;
getLeagueId(country: "brazil", season: "2019",success: { (leagueId) in

        // leagueId is the value returned from the closure
        myLeagueId = leagueId
        print(myLeagueId)
    })
下面的代码将不起作用,因为它将myLeagueId设置为getLeagueId的返回值,而getLeagueId没有返回值,因此它甚至不会编译

myLeagueId = getLeagueId(country: "brazil", season: "2019",success: { (leagueId) in
        print(leagueId)
    })

func getLeagueId不返回任何值,因此得到0。如果要从func getLeagueId获得结果,应添加将更新此值的完成处理程序函数。

func getLeagueId不返回任何值。如果您希望在网络呼叫后传输数据,则需要使用闭包。抱歉,我将对其进行编辑。它返回的是一个Int值,但我将其更改为尝试使用completion handlerAlamofire.request是异步任务,因此leagueId首先返回0,而不是Alamofire.request调用,这是获得0值的方式。@Kamran我没有检查它是否将编译。我刚才说过完成块是如何实现的。如果你能指出错误就好了。可能有错误,我只是复制了文本并编辑了它。我可以在屏幕上打印正确的值。好啊但我无法将该值赋给变量以供以后使用on@LeonardoD'Amato你在哪里赋值?@Anuraj我试过这样做:覆盖func viewDidLoad{super.viewDidLoad var leagueId=0 var id=getleagueid国家:巴西,赛季:2019,成功:{leagueId中的id=id printid}leagueId是在ViewDod load中声明的,它将不可用于viewController。很抱歉,我复制粘贴了您的代码。因此,由于函数不返回任何内容,您需要在完成块中指定值。非常感谢您的精彩解释。Manav的回答对我很有用,因为我可以打印值,但我真正想做的是打印仍然无法将此值赋给变量,然后在任何地方使用它。再次感谢