类型'Any'没有下标成员 - NSMutableArray

时间:2017-07-14 13:52:31

标签: arrays swift casting type-erasure

我们导入了一个过时的项目,它促使我们将它转​​换为Swift 3.作为对Swift知之甚少的人,我们在修复错误方面遇到了困难。 Error can be found at this image

import Foundation

class CellDescriptorHelper {

let itemKey = "Items"
let isExpandableKey = "isExpandable"
let isExpandedKey = "isExpanded"
let isVisibleKey = "isVisible"
let titleKey = "title"
let locationKey = "location"
let descriptionKey = "description"
let imageURLKey = "imageURL"
let typeKey = "type"
let cellIdentifierKey = "cellIdentifier"
let additionalRowsKey = "additionalRows"

fileprivate var cellDescriptors: NSMutableArray!
fileprivate var cellsToDisplay: NSMutableArray!

func getCellDescriptors(_ type: String) -> NSMutableArray {

    loadCellDescriptors(type)
    return cellDescriptors;
}

func loadCellDescriptors(_ type: String) {

    cellDescriptors = PlistManager.sharedInstance.getValueForKey(itemKey)! as! NSMutableArray

    for i in 0..<(cellDescriptors[0] as AnyObject).count-1 {

        let cellType = cellDescriptors[0][i][typeKey] as! String //creates error
        if(cellType != type) {
            cellDescriptors[0][i].setValue(false, forKey:  isVisibleKey) //creates error
        }
    }
}
} 

3 个答案:

答案 0 :(得分:6)

您收到此错误的原因是因为数组中对象的类型对编译器不明确。

这是因为NSArray没有具体打字。 NSArray基本上是Array<Any>[Any]

的Objective-C桥梁

让我带您完成代码......

let cellType = cellDescriptors[0][i][typeKey] as! String

编译器知道cellDescriptorsNSArray,因为它在上面被声明为一个。可以使用NSArray下标来获取给定索引处的值,就像使用cellDescriptors[0]一样。如上所述,此值给出的值为Any,因此当您尝试使用cellDescriptors[0][i]再次下标时,您将收到错误消息。碰巧,您可以将Any对象强制转换为数组,然后您就可以执行下标,如下所示:

if let newArr = (cellDescriptors[0] as? [Any])[i] { }

然而,这真的不是一个很好的方法,你最终会处理一堆讨厌的选项。

更好的方法是具体宣传cellDescriptors。我不知道你的类型结构是什么,但从事物的外观来看,它是一系列字典(yuck)。因此,在原始形式中,您的声明应为var cellDescriptors = [[[AnyHashable:Any]]](),以便像现在一样下标。

这就是说,你所拥有的代码很乱,我会考虑改变你对对象进行建模的方式,使它更有用。

答案 1 :(得分:3)

这些行有两个问题:

fileprivate var cellDescriptors: NSMutableArray!
fileprivate var cellsToDisplay: NSMutableArray!

首先,他们是!类型(隐式展开的可选或IUO)。它们应该永远不会是!类型,但在Swift 3中,它们的工作方式与它们在Swift 2中的工作方式不同,这很可能会让您失望。摆脱!并将这些分配给一个空数组来开始。 !类型仍然有用的地方很少(@IBOutlet是最适合!类型的地方之一,至少在意见方面是这样。)

另一个问题是NSMutableArray是一种草率的类型,它在Swift中造成了大量的麻烦。它只应用于非常罕见的情况,其中与Objective-C的桥梁需要它(NSMutableArray非常罕见)。

cellDescriptorscellsToDisplay转换为适当的Array类型,而不是NSMutableArray。 &#34;适当&#34;意味着&#34;实际存在的任何内容的数组。&#34;这意味着[Any]不是合适的类型。如果cellsToDisplay包含一堆Cell个对象,那么它应该是[Cell]

答案 2 :(得分:1)

NSMutableArray实际上并没有说太多...避免强行展开并尝试考虑阵列应该首先使用哪种类型。首先,数组应该在下一个数组中根据下标...所以尝试OverType它而不是NSMutableArray来输入:[[Any]]但是这个选项真的不安全!

请提供有关itemKey值应该是什么的更多信息......但总的来说,我的最佳提示是:

func loadCellDescriptors(_ type: String) {

    guard let cellDescriptors =  PlistManager.sharedInstance.getValueForKey(itemKey)? as? [[String: Any]], let firstDescriptor = cellDescriptors[0]
else { return } 


 for someKeyInDict in 0..<cellDescriptor.count{

       if let cellType = cellDescriptor[i][typeKey] as? String{
        if(cellType != type) {
            cellDescriptors[0][i].setValue(false, forKey: isVisibleKey)
        }
      }
    }

这不会100%工作,但会让你更接近,我只是提示你正在搜索的价值是字典......

相关问题