Reputation: 110
I am trying to get do a GET request, and save the following results from into NSMutuableArray. Then I am trying to load the following data I got into a tableview, but I am getting an "unexpectedly found nil while unwrapping optional value" whenever I try to configure the number of rows.
var dataArray:NSMutableArray?
Alamofire.request(.GET, "SOMERANDOMWEBSITE") .responseJSON { response in
// using if-let syntax to save json into our NSMutuableArray
if let JSON = response.result.value {
self.dataArray = JSON as? NSMutableArray
}
}
When i try to configure the number of rows:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return self.dataArray.count
}
It gives me an error: "unexpectedly found nil while unwrapping optional value". But what's strange is that when I create a random button to see if the .count is indeed nil:
@IBAction func function(sender: AnyObject) {
print(self.dataArray?.count)
}
it returns me with Optional(2) instead of nil. Any ideas?
Upvotes: 0
Views: 400
Reputation: 70097
You made your array an Optional. We can see that here:
print(self.dataArray?.count)
So until it's populated in Alamofire's closure (the network request happens in the background), it is nil.
You quote:
return self.dataArray.count
but actually you probably have done
return self.dataArray!.count
This is why it crashes.
So you have to declare another option for count for when it's nil. A solution could be to safely unwrap the array then return the count or return a default value:
if let array = self.dataArray {
return array.count
}
return 0
This same logic can be expressed in a single line, as @brian-nickel notes in the comments:
return self.dataArray?.count ?? 0
Also, as stated by @vadian in the comments, absolutely, an Optional array makes little sense here, it would be better to just have a non-optional empty array from the beginning.
Upvotes: 3
Reputation: 285069
It's not strange, it's asynchronous.
Initially you declare dataArray
as optional (aka nil
) but don't initialize it.
The first attempt to update the table view fails (crashes) because calling count
on nil
is a bad idea.
Meanwhile the asynchronous request method returns the data and assigns it to dataArray
which has now an (optional) value.
That's why you get a result in function
.
Solution is to declare and initialize the array as non-optional Swift type.
var dataArray = [AnyObject]()
Probably there is a more specific type than AnyObject
and assign the returned data accordingly casting the result to the "better" type.
Basically declaring table view data source arrays as optional is absurd since your table view is always non-optional.
Upvotes: 1