2015-05-28 3 views
2

Как я могу перебрать массив из AnyObjects в Swift и downcast в соответствующий класс одновременно? Я могу сделать это пространно, как это, но я просто не могу найти способ сделать это без «если позволить» внутри цикла:Как перебрать массив Swift [AnyObject] с downcast?

func tableView(tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [AnyObject]) { 
    var currentSort = tableView.sortDescriptors 
    for s in currentSort { 
     if let ss = s as? NSSortDescriptor { 
      println("keyPath: \(ss.key()), ascending: \(ss.ascending)") 
     } 
    } 
} 

Я пытаюсь реализовать сортировку для массива пользовательские объекты, которые являются источником данных для NSTableView.

Спасибо.

ответ

5

Если массив [AnyObject] должен быть полностью состоит из типа вы хотите, вы можете сделать ан-масс-бросок:

func tableView(tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [AnyObject]) { 
    let currentSort = tableView.sortDescriptors as? [NSSortDescriptor] 
    for s in currentSort ?? [] { 
     println("keyPath: \(s.key()), ascending: \(s.ascending)") 
    } 
} 

Это использует [] заменить пустой массив для nil вы получите, если окажется, что один или несколько из AnyObject не имеют нужного типа - вам все равно понадобится if…else, если вам нужна явная обработка ошибок, а не тихая ошибка.

Альтернативно, если вы хотите, чтобы ваша программа была в ловушке в случае сбоя, вы можете использовать as!, но тогда это немного позор, если вы обнаружите это на производстве.

Кстати, если то, что вы должны придумать новое название для развернутого значения была часть того, что вас беспокоит, вы можете просто дать ему такое же имя:

let x: Int? = 1 
if let x = x { 
    println(x) 
} 

который объявляет локальный развернутый x, который маскирует внешний x в пределах if.

Если некоторые, но не все может быть правильного типа и вы только хотите работать на тех, mapSome является удобное расширение массива, чтобы иметь вокруг:

extension Array { 
    func mapSome<U>(transform: T->U?) -> [U] { 
     return lazy(self).map(transform) 
      .filter { $0 != nil } 
      .map { $0! }.array 
    } 
} 

func tableView(tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [AnyObject]) { 
    let currentSort = tableView.sortDescriptors.mapSome { $0 as? NSSortDescriptor } 
    for s in currentSort { 
     println("keyPath: \(s.key()), ascending: \(s.ascending)") 
    } 
} 
+0

Спасибо. Это об этом. ОЧЕНЬ тщательный ответ! –