我们导入了一个过时的项目,它促使我们将它转换为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
}
}
}
}
答案 0 :(得分:6)
您收到此错误的原因是因为数组中对象的类型对编译器不明确。
这是因为NSArray
没有具体打字。
NSArray
基本上是Array<Any>
或[Any]
。
让我带您完成代码......
let cellType = cellDescriptors[0][i][typeKey] as! String
编译器知道cellDescriptors
是NSArray
,因为它在上面被声明为一个。可以使用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
非常罕见)。
将cellDescriptors
和cellsToDisplay
转换为适当的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%工作,但会让你更接近,我只是提示你正在搜索的价值是字典......