无法将元素添加到数组
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 let
或guard
语句
你可以看到下面的代码。
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()
【讨论】:
以上是关于无法将元素添加到数组的主要内容,如果未能解决你的问题,请参考以下文章