类型'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 
     } 
    } 
} 
} 
+0

请把你的代码放在像文本这样的问题上,而不是图像上。 – user28434

+1

@ user28434你好,我编辑了这篇文章。 – nkpg

+0

@Honey - 您为什么将Objective-C标签添加到有关Swift代码的问题中? – rmaddy

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

这是由于NSArray s没有具体输入的事实。 NSArray基本上是Array<Any>[Any]的Objective-C桥。

让我带你通过你的代码...

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

编译器知道cellDescriptorsNSArray,因为它被声明为上述之一。 NSArray s可以下标以获取给定索引处的值,就像您使用cellDescriptors[0]所做的那样。如上所述,这给出的值为Any,因此当您尝试使用cellDescriptors[0][i]再次下标时,您会看到您的错误。碰巧,你可能可以强制转换Any对象数组,然后你就可以执行标,就像这样:

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

然而,这真的不是一个很好的方法,你最终处理一系列讨厌的选择权。

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

这就是说,你所使用的代码是混乱的,我会考虑改变你对对象建模的方式,使它更加可用。

+2

此行'var cellDescriptors = [[[:]]]'给我一个错误:'无法调用非函数类型的值'[Array >]''移除'()'修复它或者*可能*做类似'[[[Any [cellDesciptors]]]()''是你原来的意思? – Honey

+1

尝试'var cellDescriptors = [[[String:String]]]()'。显式类型应该可以工作。 –

+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%的工作,但将让你更接近,我只是提示您正在搜索的值是字典...

+0

你能否提供一段代码来阐述你想要解释的内容? – nkpg

+0

仅当您在此处复制代码时 –

+0

非常感谢您 –

这些线有两个问题:

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

首先,他们是!类型(隐式展开的可选或IUOs)。它们不应该是!类型,但在Swift 3中,它们的工作方式与在Swift 2中的不同,这可能会打断你。摆脱!并将其分配给一个空数组以开始。有极少数的地方是!类型仍然是有用的(@IBOutlet是最后保留出局其中!类型可以是适当的,至少作为一个见仁见智的一个。)

的另一个问题是,NSMutableArray是一个草率的类型,并且它在Swift中造成了很多麻烦。它只能用于非常罕见的情况下,通往Objective-C的桥梁需要它(这在NSMutableArray中极为罕见)。

cellDescriptorscellsToDisplay转换为合适的Array类型而不是NSMutableArray。 “恰当的”意思是“一组实际在其中的事物”。这意味着[Any]不是合适的类型。如果cellsToDisplay包含一堆Cell对象,则它应该是[Cell]