Хотел узнать, есть ли у кого-нибудь понимание того, почему неоднозначное использование ошибки индекса создается в одном проекте по сравнению с другим в swift

Таким образом, на основе следующего руководства по проекту expandableCells использование суб-скриптов с NSMutableArray работает. (Я сам открыл проект в xcode и не получил ошибок)

Когда я пытаюсь использовать этот рабочий процесс в своем собственном проекте, я получаю ошибки «неоднозначное использование индекса» повсюду. Это та же проблема, что и в предыдущем вопросе Неоднозначное использование индекса

Мой вопрос будет заключаться в том, почему проект, предоставленный appcoda, работает в xcode, но аналогичный код не работает при попытке использовать аналогичный рабочий процесс в новом проекте. Имейте в виду, что проблема заключается в том, как swift обрабатывает NSMutableArray, потому что, когда я переписываю код как массив Swift и словарь, все работает, за исключением того, что нет простого способа преобразовать plist в массив Swift.

Мой plist имеет тот же формат, что и учебник: Array, Array, Dictionary.

Вот фрагмент, где я вижу ошибку

var cellDescriptors: NSMutableArray!

func loadSections() {

    let path: String = NSBundle.mainBundle().pathForResource("NewCells", ofType: "plist")!
    cellDescriptors = NSMutableArray(contentsOfFile: path)
    getIndicesOfVisibleRows()
    tblExpandable.reloadData()
}

func getIndicesOfVisibleRows() {
    visibleRowsPerSection.removeAll()

    for currentSectionCells in cellDescriptors {
        var visibleRows = [Int]()

        for row in 0...((currentSectionCells ).count - 1) {
**ERROR HERE==>** if currentSectionCells[row]["isVisible"] as! Bool == true {
                visibleRows.append(row)
            }
        }

        visibleRowsPerSection.append(visibleRows)

        print("visibleRows \(self.visibleRowsPerSection)")
    }
}

person Chris    schedule 03.08.2016    source источник
comment
Попробуйте загрузить его и использовать как [AnyObject]. var cellDescriptors: [AnyObject] = [ ] cellDescriptors = NSArray(contentsOfURL: url) as? [AnyObject] ?? []   -  person Leo Dabus    schedule 03.08.2016
comment
Это зависит от многих вещей, если применение индекса к AnyObject вызывает неоднозначное использование индекса или нет. Перечислите все импорты в вашем проекте и посмотрите, какие из них влияют.   -  person OOPer    schedule 03.08.2016
comment
@лео, это не сработало. Это вызвало неприятную ошибку ошибки сегментации. в OOPer мой единственный импорт — это UIKit. Спасибо всем за ваши ответы.   -  person Chris    schedule 03.08.2016
comment
@ cmarti1138 cmarti1138 Я почти уверен, что мой код не несет ответственности за эту ошибку, поскольку вы можете видеть, что в нем есть нулевой оператор объединения для возврата пустого массива. Эта ошибка исходит из другого места в вашем коде. Кстати, вам все еще нужно иметь дело с подэлементами вашего массива, приведенными из AnyObject в Dictionary или что-то еще. Попробуйте распечатать содержимое cellDescriptors после загрузки из файла. Просто используйте URLForResource(withExtension:) вместо pathForResource   -  person Leo Dabus    schedule 03.08.2016


Ответы (1)


Как объясняется в ответе, на который вы ссылаетесь, контейнеры Foundation (NSArray, NSDictionary и т. д.) нетипизированы. Итак, currentSelectionCells[row] возвращает AnyObject. Swift не позволит вам подписать AnyObject, так как это может быть не контейнер. Это может быть буквально что угодно.

Если вы внимательно посмотрите на код в статье AppCoda, где у вас есть

for row in 0...((currentSectionCells ).count - 1) {

у них есть

for row in 0...((currentSectionCells as! [[String: AnyObject]]).count - 1) {

Они соединили currentSelectCells с массивом Swift, содержащим словарь Swift String:AnyObject, поэтому, когда они позже говорят currentSelectionCells[row], они возвращают словарь [String:AnyObject]. Это можно подписаться, и Swift доволен.

Итак, есть простой способ преобразовать plist в массив Swift. Как правило, лучше конвертировать контейнеры Foundation в контейнеры Swift при первой же возможности, поскольку тогда вы получаете преимущества типизации членов. Было бы лучше, если бы они реализовали loadCellDescriptors как-то так:

var cellDescriptors: [[String:AnyObject]]!

func loadCellDescriptors() {
    if let path = NSBundle.mainBundle().pathForResource("CellDescriptor", ofType: "plist") {
        let plist = NSMutableArray(contentsOfFile: path)
        cellDescriptors = plist as! [[String:AnyObject]]
        getIndicesOfVisibleRows()
        tblExpandable.reloadData()
    }
}
person Paulw11    schedule 03.08.2016
comment
Спасибо за исчерпывающий ответ. Я попробовал последнюю часть работы, но мне пришлось сначала преобразовать NSMutableArray в NSArray, прежде чем я смог преобразовать его в массив Swift. В качестве еще одного эксперимента я также попытался скопировать 2 класса из файла appcoda в новые файлы в моем проекте, поскольку я полагал, что это будет работать как есть, и появились те же неоднозначные ошибки. спс за все ответы. Я отмечу это как правильный ответ. - person Chris; 04.08.2016