for-in 루프에서 유형 캐스팅
이 for-in 루프가 있습니다.
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
그러나 그것은 작동하지 않습니다.
대한 스위프트 2 이상 및 :
스위프트 2는 추가 의 경우 패턴 에 대한 더욱 쉽게하고 더 안전에 캐스트를 입력 할 수있는 루프 에 대한 루프 :
for case let button as AClass in view.subviews {
// do something with button
}
Swift 1.2 및 이전 버전 에서 할 수있는 것보다 이것이 왜 더 나은 가요? 케이스 패턴을 사용하면 컬렉션에서 특정 유형을 선택할 수 있기 때문입니다. 찾고있는 유형과 만 일치하므로 배열에 혼합이 포함되어 있으면 특정 유형에서만 작동 할 수 있습니다.
예를 들면 :
let array: [Any] = [1, 1.2, "Hello", true, [1, 2, 3], "World!"]
for case let str as String in array {
print(str)
}
산출:
Hello World!
대한 스위프트 1.2 :
이 경우에는 캐스트 view.subviews가 아닌 button캐스트이므로 원하는 유형의 배열로 다운 캐스트해야합니다.
for button in view.subviews as! [AClass] {
// do something with button
}
참고 : 기본 배열 유형이가 아닌 [AClass]경우 충돌이 발생합니다. 즉, 무엇 !에가 as!당신을 말하고있다. 유형이 확실하지 않은 경우 as?선택적 바인딩과 함께 조건부 캐스트 를 사용할 수 있습니다 if let.
if let subviews = view.subviews as? [AClass] {
// If we get here, then subviews is of type [AClass]
for button in subviews {
// do something with button
}
}
대한 스위프트 1.1 및 이전 버전 :
for button in view.subviews as [AClass] {
// do something with button
}
참고 : 하위보기가 모든 유형이 아닌 경우에도 충돌이 발생합니다 AClass. 위에 나열된 안전한 방법은 이전 버전의 Swift에서도 작동합니다.
이 옵션은 더 안전합니다.
for case let button as AClass in view.subviews {
}
또는 신속한 방법 :
view.subviews
.compactMap { $0 as AClass }
.forEach { .... }
where절을 사용할 수도 있습니다.
for button in view.subviews where button is UIButton {
...
}
vacawama가 제공 한 답변은 Swift 1.0에서 정확했습니다. 그리고 더 이상 Swift 2.0에서 작동하지 않습니다.
시도하면 다음과 유사한 오류가 발생합니다.
'[AnyObject]' is not convertible to '[AClass]';
In Swift 2.0 you need to write like:
for button in view.subviews as! [AClass]
{
}
The answers provided are correct, I just wanted to add this as an addition.
When using a for loop with force casting, the code will crash (as already mentioned by others).
for button in view.subviews as! [AClass] {
// do something with button
}
But instead of using an if-clause,
if let subviews = view.subviews as? [AClass] {
// If we get here, then subviews is of type [AClass]
...
}
another way is to use a while-loop:
/* If you need the index: */
var iterator = view.subviews.enumerated().makeIterator()
while let (index, subview) = iterator.next() as? (Int, AClass) {
// Use the subview
// ...
}
/* If you don't need the index: */
var iterator = view.subviews.enumerated().makeIterator()
while let subview = iterator.next().element as? AClass {
// Use the subview
// ...
}
Which seems to be more convenient if some elements (but not all) of the array might be of type AClass.
Although for now (as of Swift 5), I'd go for the for-case loop:
for case let (index, subview as AClass) in view.subviews.enumerated() {
// ...
}
for case let subview as AClass in view.subviews {
// ...
}
You can perform the casting and be safe at the same time with this:
for button in view.subviews.compactMap({ $0 as? AClass }) {
}
참고URL : https://stackoverflow.com/questions/26076772/type-casting-in-for-in-loop
'Programing' 카테고리의 다른 글
| 문자열이 유효한 날짜인지 확인하는 방법 (0) | 2020.08.11 |
|---|---|
| 단일 node.js 프로젝트의 몽구스 및 다중 데이터베이스 (0) | 2020.08.11 |
| Rails 모델 유형 목록 (0) | 2020.08.11 |
| 클라이언트 측에서 JavaScript의 JPEG EXIF 회전 데이터에 액세스 (0) | 2020.08.11 |
| 요구할 인수 전달 (모듈을로드 할 때) (0) | 2020.08.11 |