无法将元素添加到数组

Posted

技术标签:

【中文标题】无法将元素添加到数组【英文标题】:Cannot add element to array 【发布时间】:2017-07-06 10:33:47 【问题描述】:

我是 Swift 新手,在向数组添加元素时遇到问题

我正在尝试将 6 个对象从 JSON 存储到数组。但是 Array 是 nil。

我在调试时看到它添加到数组中,我不知道为什么在完成请求 JSON 后它是 nil?

JSON:

[
    
        "amount": "20.0",
        "date": "10/07/2016"
    ,
    
        "amount": "21.0",
        "date": "11/07/2016"
    ,
    
        "amount": "16.0",
        "date": "12/07/2016"
    ,
    
        "amount": "30.0",
        "date": "13/07/2016"
    ,
    
        "amount": "50.0",
        "date": "14/07/2016"
    ,
    
        "amount": "33.0",
        "date": "15/07/2016"
    
]

服务:

    class DownloadService 
    static let instance = DownloadService()
    //static var goldArray = [Gold]()
    var goldArray = [Gold]()
    func getData() 
        Alamofire.request("https://rth-recruitment.herokuapp.com/api/prices/chart_data", headers: headers).responseJSON  response in
            if let objJson = response.result.value as! NSArray?
                for element in objJson 
                    let data = element as! NSDictionary
                    let amount = data["amount"] as! String
                    let date = data["date"] as! String
                    let gold = Gold(amount: amount, date: date)
                    self.goldArray.append(gold)
                    print(self.goldArray.count)//print 1 to 6
                
            
        
        printGoldArray()
    

    func printGoldArray()
        for element in self.goldArray 
            print(element)//print nothing
        
    

金级:

    class Gold
    let amount:String
    let date: String

    init(amount: String, date: String) 
        self.amount = amount
        self.date = date
    


视图控制器:

    class ViewController: UIViewController 
    //var dataArray = [Gold]()
    override func viewDidLoad() 
        super.viewDidLoad()
        DownloadService.instance.getData()

    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

【问题讨论】:

这是因为您缺少异步概念。如果您在print(self.goldArray.count) 之前添加print("in alamofire closure")print("calling print") 就在printGoldArray() 之前,您会发现打印的顺序不是您所期望的。寻找“Swift + Closure + Async”。 你为什么强制解开一个可选的可选(as! NSArray?)?? 【参考方案1】:

这里printGoldArray 函数是从闭包外部调用的,这意味着当printGoldArray 被调用时,goldArray 可能没有任何值。

添加值后,尝试从闭包内部调用 printGoldArray 函数。试试下面的代码

func getData() 
    Alamofire.request("https://rth-recruitment.herokuapp.com/api/prices/chart_data", headers: headers).responseJSON  response in
        if let objJson = response.result.value as! NSArray?
            for element in objJson 
                let data = element as! NSDictionary
                let amount = data["amount"] as! String
                let date = data["date"] as! String
                let gold = Gold(amount: amount, date: date)
                self.goldArray.append(gold)
                print(self.goldArray.count)//print 1 to 6
            
        
     printGoldArray()
    


【讨论】:

其实我的目的是在其他方法中使用goldArray[],所以我将它声明为全局变量,但直到无法获取数据。那么有没有办法使用呢? 你也可以在 func getData() 中使用闭包,在完成闭包时你可以使用 goldArray 我可以在 func getData() 之外使用吗? 是的,您可以在 getData 之外使用 goldArray,但只能在执行 alamofire 的完成块/关闭之后使用 这就是为什么我的goldArray[]当时为零?我怎么知道 Alamofire 闭包的执行完成了?【参考方案2】:

在获取价值之前,您需要先解析 JSON 数据

do
    let json = try JSONSerialization.jsonObject(with: response.result.value, options: []) as? [Any]
    let firstObj = json?[0] as! [String: String]
    let amount = firstObj["amount"]
    dump(amount)
catch let error


然后,在执行闭包之前,您的 HTTP 调用不会为您获取返回值。所以要打印你的数组,你需要在你的闭包内完成。例如,您可以在 json 解析后立即执行此操作,方法是调用 printGoldArray()

【讨论】:

【参考方案3】:

首先,您的数组不是打印数组元素,因为您在关闭后直接打印它。闭包使用异步范式。所以把打印功能放在闭包里。

第二件事是为什么要大力完全展开。相反,您可以使用if letguard 语句

你可以看到下面的代码。

func getData() 
        Alamofire.request("https://rth-recruitment.herokuapp.com/api/prices/chart_data", headers: headers).responseJSON  response in
            if let objJson = response.result.value as? NSArray 
                for element in objJson 
                    if let data = element as? NSDictionary 
                        let amount = data["amount"] as! String
                        let date = data["date"] as! String
                        let gold = Gold(amount: amount, date: date)
                        self.goldArray.append(gold)
                        print(self.goldArray.count)
                    
                
            
            printGoldArray()
        
    

【讨论】:

以上是关于无法将元素添加到数组的主要内容,如果未能解决你的问题,请参考以下文章

删除元素后,子组件无法从其父组件获取数组。

无法使用指针添加数组元素

猫鼬更新数组并添加新元素

js如何往数组Array中添加元素?

js如何往数组Array中添加元素

只有最后一个元素被添加到数组中?