我只是用Alamofire和SwiftyJSON编写了一些Swift代码来访问Riot API。

我写了一个函数func getIDbyName(SummName: String) -> String来获取召唤者ID。

从下面的代码中可以看到,我将ID分配给self.SummID

执行完函数后,我能够println正确的ID,例如"1234567"。但是,return self.SummID返回"0",与开头分配的相同。

我试图弄乱代码,但是我根本无法在self.SummID闭包之外获得Alamofire.request的正确值。它始终在外部任何地方保持"0"

我认为这与变量的范围有关。有人知道这是怎么回事吗?

import Foundation

import Alamofire
import SwiftyJSON

class SummInfo {
    var SummName = "ThreeSmokingGuns"
    var SummID = "0"

    var SummChamp = "akali"
    var SummS1 = "flash"
    var SummS2 = "ignite"
    var SummRank = "Unranked"
    var SummWR = "-"        //summoner's winrate

    let api_key = "key"
    let URLinsert = "?api_key="

    init(SummName: String, SummChamp: String, SummS1: String, SummS2: String, SummRank: String, SummWR: String) {

        self.SummName = SummName
        self.SummChamp = SummChamp
        self.SummS1 = SummS1
        self.SummS2 = SummS2
        self.SummRank = SummRank
        self.SummWR = SummWR


    }

    init(SummName: String) {
        self.SummName = SummName
    }

    func getIDbyName(SummName: String) -> String
    {
        let SummURL = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/"

        var fullURL = "\(SummURL)\(SummName)\(URLinsert)\(api_key)"

        Alamofire.request(.GET, fullURL)
            .responseJSON { (request, response, data, error) in
                if let anError = error
                {
                    // got an error in getting the data, need to handle it
                    println("error calling GET on /posts/1")
                    println(error)
                }
                else if let data: AnyObject = data // hate this but responseJSON gives us AnyObject? while JSON() expects AnyObject
                    // JSON(data!) will crash if we get back empty data, so we keep the one ugly unwrapping line

                {
                    // handle the results as JSON, without a bunch of nested if loops
                    let post = JSON(data)
                    self.tempJ = post
                    var key = post.dictionaryValue.keys.array //not necessary
                    var key2 = post[SummName.lowercaseString].dictionaryValue.keys.array
                    self.SummID = post[key[0],key2[2]].stringValue  //[profileIconId, revisionDate, id, summonerLevel, name]


                    //test console output

                    println("The post is: \(post.description)")
                    println(SummName.lowercaseString)
                    println(key)
                    println(key2)
                    println(self.SummID)


                }


        }
      return self.SummID
    }
}

最佳答案

原因是

Alamofire.request(.GET, fullURL)
            .responseJSON


是一个异步调用。这意味着对getIDbyName的调用将立即返回,而无需等待responseJSON完成。这就是为什么您获得的ID最初设置为“ 0”的确切原因。

话虽如此,解决方案是在getIDbyName方法中有一个回调闭包:

 func getIDbyName(SummName: String, callback: (id:String?) ->() ) -> ()
{
        let SummURL = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/"

        var fullURL = "\(SummURL)\(SummName)\(URLinsert)\(api_key)"

        Alamofire.request(.GET, fullURL)
            .responseJSON { (request, response, data, error) in
                if let anError = error
                {
                    // got an error in getting the data, need to handle it
                    println("error calling GET on /posts/1")
                    println(error)
                    //Call back closure with nil value
                    callback(nil)  //Can additionally think of passing actual error also here


                }
                else if let data: AnyObject = data // hate this but responseJSON gives us AnyObject? while JSON() expects AnyObject
                    // JSON(data!) will crash if we get back empty data, so we keep the one ugly unwrapping line

                {
                    // handle the results as JSON, without a bunch of nested if loops
                    let post = JSON(data)
                    self.tempJ = post
                    var key = post.dictionaryValue.keys.array //not necessary
                    var key2 = post[SummName.lowercaseString].dictionaryValue.keys.array
                    self.SummID = post[key[0],key2[2]].stringValue  //[profileIconId, revisionDate, id, summonerLevel, name]


                    //test console output

                    println("The post is: \(post.description)")
                    println(SummName.lowercaseString)
                    println(key)
                    println(key2)
                    println(self.SummID)
                    //Pass the actual ID got.
                    callback(self.SummID)
                }


        }
      return self.SummID
    }


客户应该始终使用此API来获取最新的ID,并且可以直接引用该属性以获取到目前为止SummID成员中缓存的所有内容。

这是如何调用此方法的-

object.getIDbyName(sumName){ (idString :String) in

      //Do whatever with the idString

}

关于ios - 无法更改全局变量的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30721679/

10-11 22:42