问题
I have a expandable table with custom cells that appear or disappear when a visible row is tapped. The cell's data is stored in a plist and declared as a NSMutableArray.
I get an 'ambiguous use of subscript' error in the following code and was hoping somebody else has encountered this and know the fix. I've tried all possible options, to my limited knowledge I must add.
var cellDescriptors: NSMutableArray!
func getCellDescriptorForIndexPath(indexPath: NSIndexPath) -> [String: AnyObject] {
let indexOfVisibleRow = visibleRowsPerSection[indexPath.section][indexPath.row]
let cellDescriptor = cellDescriptors[indexPath.section][indexOfVisibleRow] as! [String: AnyObject]
return cellDescriptor
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row]
if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] as! Bool == true { // Ambiguous use of subscript error
var shouldExpandAndShowSubRows = false
if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] as! Bool == false { // Ambiguous use of subscript error
// In this case the cell should expand.
shouldExpandAndShowSubRows = true
}
回答1:
The compiler is telling you it can't be sure the type of object you're subscripting can actually be subscripted. You haven't provided any information about what you call a "cell descriptor" so it's hard to say for sure what the problem is, but it looks like you're expecting a dictionary to be returned from whatever the subscript call with indexOfTappedRow
looks up.
This is probably due to using Cocoa collections like NSArray
/ NSMutableArray
, and NSDictionary
/ NSMutableDictionary
, which are containers of AnyObject
(which loses type information about what exactly it's storing). Since these are toll-free bridged to Swift arrays and dictionaries, it's easy enough to change your model (including containers) to use specific types so that your containers can declare, definitively, that they're "an array of CellDescriptor
" (versus NSArray
's "an array of some random kind of object (AnyObject
)"). This way, you don't have to do unsavory things like looking up properties by some error-prone string you may mistype here or there (which is made worse by your use of as!
, which demands it be "valid or explode" versus "true or false").
Treat Swift's strong type system as something to be taken advantage of rather than as something to avoid if possible. Things really do become a lot easier.
Update for Comment
In this case (since a PLIST is a pure Cocoa object graph), you can just expand your code to take things one step at a time. That is:
- Get the section as an array of dictionaries (we assume this structure because it's a PLIST of a structure known to you but there's always room for the unexpected...)
- Get the dictionary for the row
as? NSDictionary
(hint:if let...
) - Get value for
"isExpanded"
keyas? NSNumber
(hint:if let...
) - If you've gotten this far, use the
NSNumber
'sboolValue
. No ambiguities.
回答2:
Cor, I'm assuming you resolved this by now but having found a solution, I thought I would bring it to your attention:
func getCellDescriptorForIndexPath(indexPath: NSIndexPath) -> [String: AnyObject] {
let indexOfVisibleRow = visibleRowsPerSection[indexPath.section][indexPath.row]
// HERE IS WHAT YOU WANT:
let cellDescriptor = (cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfVisibleRow] as! [String: AnyObject]
return cellDescriptor
}
回答3:
if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] as! Bool == true {
var shouldExpandAndShowSubRows = false
if cellDescriptors[indexPath.section][indexOfTappedRow]["isExpanded"] as! Bool == false { // Ambiguous use of subscript error
// In this case the cell should expand.
shouldExpandAndShowSubRows = true
}
}
Should be replaced with:
if **((cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfTappedRow] as AnyObject)["isExpandable"] as! Bool** == true {
var shouldExpandAndShowSubRows = false
if ((cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfTappedRow] as AnyObject)["isExpanded"] as! Bool == false {
// In this case the cell should expand.
shouldExpandAndShowSubRows = true
}
}
来源:https://stackoverflow.com/questions/33915840/ambiguous-use-of-subscript