类型'Any'没有下标成员 - NSMutableArray
我们导入了一个过时的项目,它促使我们将其转换为Swift 3.作为对Swift不太了解的个人,我们在修复错误时遇到困难。 Error can be found at this image类型'Any'没有下标成员 - NSMutableArray
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
}
}
}
}
您得到此错误的原因是因为数组中的对象的类型对编译器不明确。
这是由于NSArray
s没有具体输入的事实。 NSArray
基本上是Array<Any>
或[Any]
的Objective-C桥。
让我带你通过你的代码...
let cellType = cellDescriptors[0][i][typeKey] as! String
编译器知道cellDescriptors
是NSArray
,因为它被声明为上述之一。 NSArray
s可以下标以获取给定索引处的值,就像您使用cellDescriptors[0]
所做的那样。如上所述,这给出的值为Any
,因此当您尝试使用cellDescriptors[0][i]
再次下标时,您会看到您的错误。碰巧,你可能可以强制转换Any
对象数组,然后你就可以执行标,就像这样:
if let newArr = (cellDescriptors[0] as? [Any])[i] { }
然而,这真的不是一个很好的方法,你最终处理一系列讨厌的选择权。
更好的方法是具体声明cellDescriptors
。我不知道你的类型结构如何,但从外观上看,它是一系列字典(yuck)。因此,在原始形式中,您的声明应该是var cellDescriptors = [[[AnyHashable:Any]]]()
,以便像现在一样下标。
这就是说,你所使用的代码是混乱的,我会考虑改变你对对象建模的方式,使它更加可用。
此行'var cellDescriptors = [[[:]]]'给我一个错误:'无法调用非函数类型的值'[Array
尝试'var cellDescriptors = [[[String:String]]]()'。显式类型应该可以工作。 –
是的,我的坏,我越来越混杂的赋值和声明语法。 –
的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%的工作,但将让你更接近,我只是提示您正在搜索的值是字典...
这些线有两个问题:
fileprivate var cellDescriptors: NSMutableArray!
fileprivate var cellsToDisplay: NSMutableArray!
首先,他们是!
类型(隐式展开的可选或IUOs)。它们不应该是!
类型,但在Swift 3中,它们的工作方式与在Swift 2中的不同,这可能会打断你。摆脱!
并将其分配给一个空数组以开始。有极少数的地方是!
类型仍然是有用的(@IBOutlet
是最后保留出局其中!
类型可以是适当的,至少作为一个见仁见智的一个。)
的另一个问题是,NSMutableArray
是一个草率的类型,并且它在Swift中造成了很多麻烦。它只能用于非常罕见的情况下,通往Objective-C的桥梁需要它(这在NSMutableArray
中极为罕见)。
将cellDescriptors
和cellsToDisplay
转换为合适的Array
类型而不是NSMutableArray
。 “恰当的”意思是“一组实际在其中的事物”。这意味着[Any]
不是合适的类型。如果cellsToDisplay
包含一堆Cell
对象,则它应该是[Cell]
。
请把你的代码放在像文本这样的问题上,而不是图像上。 – user28434
@ user28434你好,我编辑了这篇文章。 – nkpg
@Honey - 您为什么将Objective-C标签添加到有关Swift代码的问题中? – rmaddy