[Swift] #로 시작하는 키워드 알아보기
#if
, #elseif
, #else
, #endif
, #sourceLocation
, #error
, #warning
, #available
살펴보기
들어가기 전에
개-하! 제목을 #
로 시작하는 키워드 알아보기라고 했지만,, 이거는 사실 저번 에 쓴 글까지 다 봐야 커버 가능한 내용입니다.. ㅎ 그 와중에 빼먹은 것도 있는건 안비밀,, 튼 적당한 제목이 생각이 안나서 일단 저렇게 지어버림 ㅇㅇ!
지난 시간에는 #file
, #line
등 #
으로 시작하는 literal 들에 대해 알아봤슴니다.
근데 저는 사실 저 부분 공부할 때 #if
같은 키워들도 같이 나올줄 알았거든여?? 그러니까 #
으로 시작하는 애들 설명이 다 한군데 묶여있을줄 알았단 말이져??!
하지만 어림 없지!!! 요 많은 것들 중에 우리가 Expressions 문서를 통해 살펴본건,, 요 정도?! 였어염
- Special literal —
#file
,#fileID
,#filePath
,#line
,#column
,#function
,#dsohandle
- Playground literal —
#colorLiteral
,#fileLiteral
,#imageLiteral
딱 봐도 많이 비어보이져? ㅎㅎ
사실 #keypath
, #selector
는 Expressions 문서에서 각각 Key-Path String Expression 과 Selector Expression 으로 다루고 있긴한데, 오늘 제가 궁금한 부분은 아니니까 넘어가기로 하고요??
오늘은 Statements 문서에서 찾을 수 있는 #
로 시작하는 키워드들에 대해 알아볼겁니다요
- Conditional Compilation Block —
#if
,#elseif
,#else
,#endif
- Line Control Statement —
#sourceLocation
- Compile-Time Diagnostic Statement —
#error
,#warning
- Availability Condition-
#available
그럼 고고링~
Conditional Compilation Block (조건부 컴파일 블록)
Conditional Compilation Block을 사용하면 코드를 조건부로 컴파일할 수 있다고 합니다.
🤔 어떻게??
바로 #if
나 #endif
같은 컴파일러 지시어(compilation directive) 를 통해서요!!
가장 단순한 조건부 컴파일 블록은 요렇게 생겼습니다
Conditional Compilation Block 이라는 이름답게, 컴파일 시점에 조건이 true일때만 statement 가 컴파일되고 실행됩니다.
컴파일 조건으로는 true
/false
가 들어갈수도 있고, 아래 표에 나열된 platform condition 중 하나가 될 수도 있습니다
바로 바로 os(iOS)
/ arch(i386)
/ targetEnvironment(simulator)
요런 식으로 ()
안에 argument 를 넣어서 참/거짓 조건을 만들어주면 되는건디! 코드를 볼까여??
#if compiler(>=5)
print("Compiled with the Swift 5 compiler or later")
#endif#if swift(>=4.2)
print("Compiled in Swift 4.2 mode or later")
#endif#if compiler(>=5) && swift(<5)
print("Compiled with the Swift 5 compiler or later in a Swift mode earlier than 5")
#endif
여기서 조건을 더 추가하고 싶다면 #elseif
와 #else
를 사용하면 됩니다
Line Control Statement (라인 제어 구문)
Line Control Statement을 사용하여 Swift가 진단(diagnostic) 및 디버깅 목적으로 사용하는 소스 코드의 위치를 변경할 수 있습니다
먼소리냐고여?? 저도 모르겠는데요??
저랑 비슷한 사람이 있었는지 Line Control Statements 를 애플 문서에서 읽긴했는데 언제 써야하는거임?? 이라는 질문이 있더라구여
답변은
니 전체 경력 통틀어서도 쓸 일 없을지도~ 아마 소스코드 generate 하는데 필요한 툴에 사용될텐데 튼 너는 사용할 일 없을테니 걱정 마셈 ㅇㅇ
??????????? 이런 답변을 원했던ㄱ ㅔ 아니거든?!!!
후,, 정보의 바다에서 원하는 내용들을 잘 캐내봅시다,,
우선 요 친구부터!
file path 로 들어가는 값은 #file
, #fileID
, #filePath
의 값을 변경하고, line number 은 #line
값을 변경한다네여
요런 #file
, #fileID
, #filePath
, #line
이 뭔지 잘 모르겠다면 제 이전 글을 보고 오시기로 하고,, 그래서 어떻게 쓰이는건데??
일단 걍 #file
이랑 #line
을 playground에서 찍어볼게여
제 파일이랑 해당하는 line number 제대로 찍혔구여?
이제 #sourceLocation
키워드를 이용해서 파일명이랑 line 넘버를 재지정한다음 똑같이 #file
이랑 #line
을 찍어볼게여
홀뤼몰뤼,,, 제가 sourceLocation 에서 지정한대로 파일 이름이랑 기준 line 이 변경됐네여
#line
이 101로 찍히는건 #sourceLocation
으로 지정한 line 의 다음 줄 부터가 해당 값으로 지정 되기 때문인가봐요 👀
그리고 file 과 line 파라미터를 받지 않는 #sourceLocation()
란 애도 있는디
얘는 설명에
소스 코드 위치를 default line 번호 및 파일 경로로 재설정합니다
라고 써있길래 저는 #sourceLocation(file:_,line:_)
을 통해 내 멋대로 설정해놓은 경로들을 다시 되돌려주는줄 알았쪄?? 애초에 쟤만 단독으로 쓰려면 에러가 나기도 하고욤
한번 찍어볼까요?
??? 제 예상은 myplay.playground
와 17
이 다시 찍히는거였는데, 왜 냅다 var/folders/k1/6kbxtts16gq6pyl2wc386gpc0000gn/T/playground33-f556c0..swift
랑 27
이 찍혀버리는,,?
광기의 한국인,, 집착의 한국인,, 저 경로로 들어가본다,,
응??? 제가 playground 를 열고 작성한건 11번째 라인에 있는 import UIKit
부터거든여?? 근데 playground 생성할 때 저도 모르는 사이에 자동으로 생기는 라인들이 있었네여??
여기서 자동으로 생성된 코드들 중 마지막 라인인 10번째 라인을 볼게요
#sourceLocation(file: “myplay.playground”, line: 1)
응,,?? sourceLocation,,??????? 너가 왜 여기서 나와,,????
와 이 코드 때문에 처음 playground 에서 단순히 #file
이랑 #line
을 찍었을때 myplay.playground
와 line number 가 9
로 나왔던건가봐요;;
아까는 myplay.playground
와 9
을 보고 “파일이랑 해당하는 line number 제대로 찍혔구여?” 라고 했었지만 사실은 sourceLocation 의 농간에 놀아나버렸던거임;;
찐 file과 line 값은 #sourceLocation()
으로 소스 코드 위치를 default line 번호 및 파일 경로로 재설정했을때 찍힌 값들이었던것이져,, 홀뤼~
오키 그러면 다시 정의를 살펴 봤을 때
#sourceLocation(file:_,line:_)
— #file
과 #line
번호 customize 가능
#sourceLocation()
— 소스 코드 위치를 default line 번호 및 파일 경로로 재설정
이제 설명 봐도 뭔지 ㅇㅣ해 완료!
Compile-Time Diagnostic Statement (컴파일 타임 진단 구문)
컴파일 타임 진단 구문은 컴파일 중에 오류나 경고를 발생시킵니다.
우선 #error
같은 경우에는 fatal error로 오류 메시지를 내보내고 컴파일 프로세스를 종료합니다.
#warning
은 nonfatal warning 으로 경고 메시지를 표시하며 컴파일을 진행할 수 있습니다.
안에 들어가는 메시지는 static string literal로 작성합니다. 따라서 문자열 보간이나 연결과 같은 기능을 사용할 수 없습니다. 그러나 여러 줄로 된 문자열은 사용할 수 있습니다.
예시를 보면 뭔 말인지 바로 이해 될걸여?
오키? 오키!
Availability Condition (가용성 조건)
#available
키워드로 시작하는 이 조건은 ()
안에 플랫폼 이름과 버전이 들어갑니다.
if #available(iOS 11.0, *) { }
이는 즉, 현재 실행 환경 버전이 iOS 11.0
이상인지를 확인하는건데요!
🤔 ?? 나는 iOS 11.0
만 명시했는데, “그 이상” 인지를 확인하는거라고??
바로 마지막에 필수로 들어가는 인자인 *
가 해당 버전 이상인지를 체크하는 역할을 합니다.
iOS
, macOS
, watchOS
, tvOS
등 다양한 플랫폼의 이름과 대응하는 version number를 짝지어서 추가할 수 있어요!
if #available(iOS 11.0, macOS 10.12, *) { }
이렇게 if
, while
, guard
문의 조건으로 들어가는 #available
을 통해서 사용할 API가 runtime에 사용 가능한지를 체크하고 실행합니다
먼 말이냐면! 현재 제 프로젝트의 iOS Deployment Target 은 14.1 이에여
근데 여기서 iOS 15.0 부터 사용할 수 있는 data(for:delegate:)
함수를 사용한다??
응 어림없어~
이건 iOS 15.0 이상에서 쓸 수 있는거셈 ㅇㅇ 하고 바로 에러 뱉어버리는디요 친절하게 이 에러를 해결할 수 있는 몇가지 방법을 제시해주네여
첫번째는 if #available
로 버전 체크한 다음에 data(for:deleagate)
를 사용하셈
두세번째는 @available
붙여서 data(for:deleagate)
를 포함하고 있는 함수나 클래스 자체를 iOS 15 이상에서만 호출 할 수 있게 하셈
이라는 건데 저희가 알아보고 싶은건 첫번째니까 저걸 클릭해볼게여
짜쟌 에러가 없어졌습니다. #available
을 통해서 사용할 API가 runtime에 사용 가능한지를 체크하고 실행한다는 뜻이 이제 뭔지 와닿으시나여?? 15 미만 버전을 위해서는 else
쪽에서 처리해주면 되겠져~~
그리고 availability condition 은 &&
나 ||
같은 논리 연산자를 사용해서 결합할 수 없습니다
요런게 안된다는 말이겠져?
마무리
좋아여 오늘은 #
로 시작하는 swift 의 키워드 중 Statements 문서에 나와있는 것들을 살펴봤는데여!
- Conditional Compilation Block —
#if
,#elseif
,#else
,#endif
- Line Control Statement —
#sourceLocation
- Compile-Time Diagnostic Statement —
#error
,#warning
- Availability Condition-
#available
이제 저번 시간에 살펴본 내용들과 합치면 (from Expresions 문서)
- Special literal —
#file
,#fileID
,#filePath
,#line
,#column
,#function
,#dsohandle
- Playground literal —
#colorLiteral
,#fileLiteral
,#imageLiteral
대충 #
로 시작하는 swift 의 키워드들은 거의 살펴본 것 같습니다?!
그럼 이쯤에서 마무리하는 것으로 하며,,, 모두들 해피 설날~~!!!!!