enumerateObjectsUsingBlock - приведение параметров в Swift
Я хочу сослаться на перечисленные объекты с их конкретным типом, а не просто общий AnyObject!
, но не могу найти никакой информации об этом в документации.
Подпись enumerateObjectsUsingBlock
в Свифте есть:
func enumerateObjectsUsingBlock(_ block: ((AnyObject!,
Int,
UnsafePointer<ObjCBool>) -> Void)!)
и в Задаче C:
- (void)enumerateObjectsUsingBlock:(void (^)(id obj,
NSUInteger idx,
BOOL *stop))block
Если я хочу обрабатывать объекты, которые повторяются, как определенный тип, в Objective CI просто настройте подпись на лету, например:
[array enumerateObjectsUsingBlock:^(NSString *s, NSUInteger idx, BOOL *stop){
// ...some function of s as NSString, not just id...
}];
Как мне получить это поведение в Swift?
2 ответа
В Swift вы не можете "подправить" подпись блока / замыкания, как в Objective-C, вы должны привести в явном виде. Либо с дополнительным приведением:
array.enumerateObjectsUsingBlock({ object, index, stop in
if let str = object as? String {
println(str)
}
})
или с принудительным приведением, если вы уверены, что все объекты являются строками:
array.enumerateObjectsUsingBlock({ object, index, stop in
let str = object as String // `as!` in Swift 1.2
println(str)
})
поскольку NSArray
мосты к Array
Вы можете без проблем использовать Array
перечисление:
for str in array as [String] {
println(str)
}
или, если вам нужны элементы вместе с их индексом:
for (index, str) in enumerate(array as [String]) {
println("\(index): \(str)")
}
Обновление для Swift 3.0
С enumerateObjects(using:)
:
array.enumerateObjects(using: { (object, index, stop) in
if let str = object as? String {
print("\(index): \(str)")
}
})
Перечислите как массив Swift:
if let a = array as? [String] {
for str in a {
print(str)
}
}
Перечислите элементы и индексы в виде массива Swift:
if let a = array as? [String] {
for (index, str) in a.enumerated() {
print("\(index): \(str)")
}
}
Я рекомендую использовать оператор swift for/each, который автоматически предоставляет каждый элемент в качестве переменной типа, содержащегося в массиве swift:
let array: [String] = ["1", "2", "3"]
for element in array {
println(element) // element is of String type
}
С NSArray
Вы можете использовать то же утверждение, но с явным приведением:
let nsarray: NSArray = ["1", "2", "3"]
for element in nsarray {
let value = element as String // note: use `as!` in swift 1.2
println(value)
}
Если вы все еще используете enumerateObjectsUsingBlock
:
nsarray.enumerateObjectsUsingBlock { (element, index, stop) in
let stringElement = element as String
println(stringElement)
}