У меня есть этот цикл:
for button in view.subviews {
}
Теперь я хочу, чтобы кнопка была преобразована в специальный класс, чтобы я мог использовать ее свойства.
Я пробовал это: for button in view.subviews as AClass
Но это не работает и выдает ошибку:'AClass' does not conform to protocol 'SequenceType'
И я попробовал это: for button:AClass in view.subviews
Но и это не работает.
for-loop
swift
for-in-loop
Arbitur
источник
источник
for button in view.subviews as [AClass]
Ответы:
Для Swift 2 и новее:
Swift 2 добавляет шаблоны case в циклы for , что делает еще проще и безопаснее вводить приведение в цикле for :
Почему это лучше, чем то, что вы могли сделать в Swift 1.2 и ранее? Потому что шаблоны кейсов позволяют выбрать из коллекции именно ваш тип. Он соответствует только тому типу, который вы ищете, поэтому, если ваш массив содержит смесь, вы можете работать только с определенным типом.
Например:
Вывод:
Для Swift 1.2 :
В этом случае вы выполняете преобразование,
view.subviews
а неbutton
преобразование, поэтому вам нужно преобразовать его в массив нужного вам типа:Примечание. Если базовый тип массива не является типом
[AClass]
, произойдет сбой. То есть то , что!
наas!
это говорит вам. Если вы не уверены в типе, вы можете использовать условное приведениеas?
вместе с необязательной привязкойif let
:Для Swift 1.1 и ранее:
Примечание. Это также приведет к сбою, если все подпредставления не относятся к типу
AClass
. Указанный выше безопасный метод также работает с более ранними версиями Swift.источник
[ ]
скобки, как в этом примере. Может быть, это только я, но сначала я подумал, что это просто выбор форматирования в примере кода :) Я предполагаю, что это потому, что мы выполняем преобразование в массив.[Class]
выглядит намного лучше, чемArray<Class>
.Этот вариант более безопасен:
или быстрый способ:
источник
Вы также можете использовать
where
предложениеисточник
button
внутри тела цикла, что является целью других решений. Таким образом, это будет запускать тело цикла только для элементов, уview.subviews
которых естьUIButton
s, но не помогает, например, при вызовеAClass
специфичных для него методовbutton
.where
только охраняет и не кастует .where
может быть более элегантным и удобочитаемым для случаев (случайный каламбур), когда вам нужна только логическая защита.Приведенные ответы верны, я просто хотел добавить это в качестве дополнения.
При использовании цикла for с принудительным приведением код выйдет из строя (как уже упоминалось другими).
Но вместо использования предложения if
другой способ - использовать цикл while:
Что кажется более удобным, если некоторые элементы (но не все) массива могут иметь тип
AClass
.Хотя пока (начиная со Swift 5), я бы выбрал цикл for-case:
источник
Ответ Vacawama был правильным в Swift 1.0. И больше не работает со Swift 2.0.
Если вы попытаетесь, вы получите ошибку, похожую на:
В Swift 2.0 вам нужно написать так:
источник
Вы можете выполнить кастинг и при этом быть в безопасности с этим:
источник