casting - Type 'Any' has no subscript members AND Value of type 'Any' has no member 'Count' -
i receiving following 2 errors below when creating array of strings in swift 3.0 on xcode8:
value of type 'any' has no member 'count'
- original code: return tododata.count
- "fixed" with: return (tododata anyobject).count
type 'any' has no subscript members
- original code: if let text = tododata[indexpath.row] {
see full code below:
let tododata = userdefaults.standard.value(forkey: "todosarray") override func tableview(_ tableview: uitableview, numberofrowsinsection section: int) -> int { if let tododata = tododata { return tododata.count //error 1. } else { return 0 } } override func tableview(_ tableview: uitableview, cellforrowat indexpath: indexpath) -> uitableviewcell { let cell = tableview.dequeuereusablecell(withidentifier: "reuseidentifier", for: indexpath) as! tableviewcell if let tododata = tododata { if let text = tododata[indexpath.row] { //error 2. cell.label.text = text as? string } } return cell }
your issue
is here:
let tododata = userdefaults.standard.value(forkey: "todosarray")
the compiler has inferred type of tododata
to any?
, because line calls userdefaults
override of nsobject
method value(forkey:)
, returns any?
. can see option-clicking variable. type any?
doesn't have property count
, or subscript takes int
.
the naive solution cast it:
let tododata = userdefaults.standard.value(forkey: "todosarray") as? [todo]
but better option replace value(forkey:)
call array(forkey:)
, cast you:
let tododata = userdefaults.standard.array(forkey: "todosarray")
as side note...
this code:
override func tableview(_ tableview: uitableview, numberofrowsinsection section: int) -> int { if let tododata = tododata { return tododata.count //error 1. } else { return 0 } }
can expressed more as:
override func tableview(_ tableview: uitableview, numberofrowsinsection section: int) -> int { return tododata.count ?? 0 }
this uses null coalescing operator (??
). can find out more that, here.
and code:
override func tableview(_ tableview: uitableview, cellforrowat indexpath: indexpath) -> uitableviewcell { let cell = tableview.dequeuereusablecell(withidentifier: "reuseidentifier", for: indexpath) as! tableviewcell if let tododata = tododata { if let text = tododata[indexpath.row] { //error 2. cell.label.text = text as? string } } return cell }
can rewritten as:
override func tableview(_ tableview: uitableview, cellforrowat indexpath: indexpath) -> uitableviewcell { let cell = tableview.dequeuereusablecell(withidentifier: "reuseidentifier", for: indexpath) as! tableviewcell cell.label.text = tododata?[indexpath.row] as? string return cell }
this uses subscripting optional chaining. can read more that, here.
Comments
Post a Comment