신속한 숫자 및 CGFloat (CGPoint, CGRect 등)
실생활에서 자주 발생하는 것처럼 CGRect 및 CGPoint와 관련하여 Cocoa Touch와 통신해야 할 때 특히 서투른 Swift 숫자를 발견하고 있습니다 (예 : 무언가 frame
또는 에 대해 이야기하고 있기 때문입니다 bounds
).
CGFloat 대 더블
UIViewController 하위 클래스에서 다음과 같은 순진한 코드를 고려하십시오.
let scale = 2.0
let r = self.view.bounds
var r2 = CGRect()
r2.size.width = r.size.width * scale
이 코드는 컴파일에 실패하며 마지막 줄에 일반적인 신비한 오류가 있습니다.
제공된 인수를 허용하는 '*'에 대한 오버로드를 찾을 수 없습니다.
지금까지 알고 계시 겠지만이 오류는 유형 간의 임피던스 불일치를 나타냅니다. r.size.width
CGFloat로 도착하여 Swift Float와 자동으로 교환되지만 Swift Double 변수 (기본값)와 상호 운용 할 수 없습니다 scale
.
예제는 인위적으로 간단하므로 scale
처음부터 Float 로 캐스팅하는 인위적으로 간단한 솔루션 이 있습니다. 그러나 제안 된 CGRect 요소의 계산에 모든 곳에서 도출 된 많은 변수가 관련 될 때해야 할 일이 많습니다.
Verbose Initializer
또 다른 자극은 새로운 CGRect를 만들 때가되면 일어나는 일입니다. 문서에도 불구하고 값이 있지만 레이블이없는 이니셜 라이저는 없습니다. Doubles가 있기 때문에 컴파일에 실패합니다.
let d = 2.0
var r3 = CGRect(d, d, d, d)
그러나 d
Float로 캐스트하더라도 컴파일하지 않습니다.
호출에서 인수 레이블 'x : y : width : height :'누락
따라서 우리 CGRectMake
는 Objective-C에서 개선되지 않은. 그리고 때로는 CGRectMake와 CGSizeMake가 개선되지 않습니다. 내 앱 중 하나의 실제 코드를 고려하십시오.
let kSEP : Float = 2.0
let intercellSpacing = CGSizeMake(kSEP, kSEP);
내 프로젝트 중 하나에서 작동합니다. 또 다른 경우에는 똑같은 코드가 불가사의하게 실패합니다! —이 오류 :
'NSNumber'는 'CGFloat'의 하위 유형이 아닙니다.
때로는 Swift가 Float를 NSNumber로 캐스팅하여 "다리 건너기"를 시도하는 것과 같습니다. 물론 브리지의 다른쪽에있는 것이 CGFloat를 예상 할 때 수행하는 잘못된 작업입니다. 나는 오류가 하나에는 나타나지만 다른 하나에는 나타나지 않는 두 프로젝트의 차이점을 아직 파악하지 못했습니다 (아마도 다른 사람이 있습니다).
참고 : 이 문제를 파악했을 수 있습니다. Build Active Architecture Only 빌드 설정에 따라 달라지는 것 같습니다. 이는 64 비트 문제임을 나타냅니다. Float는 64 비트 장치에서 CGFloat와 일치하지 않기 때문에 의미가 있습니다. 이는 임피던스 불일치 문제가 내가 생각했던 것보다 훨씬 더 나쁘다는 것을 의미합니다.
결론
이 주제에 대한 실용적인 지혜의 말을 찾고 있습니다. 나는 누군가가 삶을 훨씬 더 쉽게 만들어 줄 CGRect 및 CGPoint 확장을 고안했을 수 있다고 생각합니다. (또는 누군가가 CGFloat를 Int 또는 Double과 결합하는 것과 같은 추가 산술 연산자 함수 오버로드의 보트로드를 작성했을 수도 있습니다. 가능하다면 작동합니다.)
Int, CGFloat 및 Double 간의 상호 작용을 허용하기 위해 연산자 오버로딩을 처리하는 라이브러리를 작성했습니다.
https://github.com/seivan/ScalarArithmetic
베타 5부터 현재 바닐라 스위프트로 할 수없는 작업 목록이 있습니다. https://github.com/seivan/ScalarArithmetic#sample
무슨 일이 일어나고 있는지보기 위해 ScalarArithmetic을 사용하거나 사용하지 않고 테스트 스위트를 실행하는 것이 좋습니다.
당신이 발견 했듯이 명시 적으로 입력 scale
하는 CGFloat
것은 실제로 입력 문제를 신속하게 처리하는 방법입니다. 다른 사람을위한 참고를 위해 :
let scale: CGFloat = 2.0
let r = self.view.bounds
var r2 = CGRect()
r2.size.width = r.width * scale
두 번째 질문에 어떻게 답해야할지 모르겠다면 다른 제목으로 별도로 게시하는 것이 좋습니다.
최신 정보:
Swift 제작자이자 수석 개발자 인 Chris Lattner는 2014 년 7 월 4 일 Apple Developer Forum 에서이 문제에 대해 이렇게 말했습니다 .
여기서 일어나는 일은 CGFloat가 32 비트 또는 64 비트 용으로 빌드하는지 여부에 따라 Float 또는 Double에 대한 typealias라는 것입니다. 이것이 정확히 Objective-C가 작동하는 방식이지만 Swift에서는 암시 적 변환을 허용하지 않기 때문에 Swift에서는 문제가됩니다.
우리는이 문제를 알고 있으며 심각하다고 생각합니다. 현재 여러 가지 솔루션을 평가하고 있으며 이후 베타에서 하나를 출시 할 것입니다. 아시다시피 Double로 캐스팅하여 오늘이 문제에 대처할 수 있습니다. 이것은 우아하지 않지만 효과적입니다 :-)
Xcode 6 베타 5 업데이트 :
CGFloat는 모든 Integer 유형 (크기가 지정된 정수 유형 포함)으로 구성 될 수 있으며 그 반대의 경우도 마찬가지입니다. (17670817)
계산 된 CGFloatValue 속성을 추가하는 Double 및 Int에 대한 확장을 만들었습니다.
extension Double {
var CGFloatValue: CGFloat {
get {
return CGFloat(self)
}
}
}
extension Int {
var CGFloatValue: CGFloat {
get {
return CGFloat(self)
}
}
}
다음을 사용하여 액세스합니다. let someCGFloat = someDoubleOrInt.CGFloatValue
Also, as for your CGRect Initializer, you get the missing argument labels error because you have left off the labels, you need CGRect(x: d, y: d, width: d, height: d)
you can't leave the labels out unless there is only one argument.
참고URL : https://stackoverflow.com/questions/24108827/swift-numerics-and-cgfloat-cgpoint-cgrect-etc
'Development Tip' 카테고리의 다른 글
WChars, 인코딩, 표준 및 이식성 (0) | 2020.12.05 |
---|---|
문서화 된 JavaScript 함수에 대한 Github 친화적 마크 다운을 쉽게 만드는 방법은 무엇입니까? (0) | 2020.12.05 |
Pure-Ruby 동시 해시 (0) | 2020.12.05 |
부분보기에 JavaScript를 넣어도 괜찮습니까? (0) | 2020.12.05 |
NPM으로 패키지를 설치할 때 종속성 중 하나의 다른 버전을 사용하도록 지정할 수 있습니까? (0) | 2020.12.05 |