검색결과 리스트
로그의 노트에 해당되는 글 212건
- 2015.06.22 [swift] Map, Filter, Reduce
- 2015.06.19 [swift2] New in Swift2.0
- 2015.06.10 [swift] Apple Swift Blog
- 2014.11.30 [앱개발] 글 목록
- 2014.10.29 [swift] Swift 기초 - 4
- 2014.10.29 [swift] Swift 기초 - 3 (1)
- 2014.10.29 [swift] Swift 기초 - 2
- 2014.10.29 [swift] Swift 기초 - 1 (1)
- 2014.10.20 [Xcode] 지원 시뮬레이터 목록을 출력하는 명령
- 2014.04.24 서른살에 알았더라면 좋았을 것들
글
[swift] Map, Filter, Reduce
함수를 인자로 취하는 함수를 고차원 함수(higher-order function)라고 합니다.
Swift 표준라이브러리에서 array의 메서드로 제공하는 고차원 함수인 map, filter, reduce에 대해서 알아보겠습니다.
1. Map
func map<U>(transform: (T) -> U) -> Array<U>
Map은 배열 각 요소 x에 변환함수 transform을 적용하고 그 결과값으로 구성된 배열을 반환하는 함수입니다.
배열요소들을 다른 값으로 맵핑하는 함수이지요.
2. Filter
func filter(includeElement: (T) -> Bool) -> Array<T>
Filter는 조건식을 인자로 받아, 조건식이 true를 만족하는 요소들로만 구성된 배열을 반환하는 함수입니다.
쉽게 말하면, 배열요소들을 필터링하는 함수입니다.
3. Reduce
func reduce<U>(initial: U, combine: @noescape (U, T) -> U) -> U
Reduce는 U를 초기값으로 하여,각 배열요소들과 순차적으로 결합연산을 하여 누적된 단일값을 반환하는 함수입니다.
4. 사용예
이제 사용법에 대해서 알아볼까요? 다음과 같은 정수형 배열이 있습니다.
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- 1. 정수형 배열의 각 요소에 1을 더한 배열을 얻고 싶다.
- 2. 정수형 배열의 각 요소에 2를 곱한 배열을 얻고 싶다.
- 3. 정수형 배열에서 짝수로만 구성된 배열을 얻고 싶다.
- 4. 정수형 배열 값들의 총합을 얻고 싶다.
map 함수를 사용하여 1,2번 문제의 답을 쉽게 얻을 수 있습니다.
// 1. 정수형 배열의 각 요소에 2를 곱한 배열을 얻고 싶다.
arr.map { (x) -> Int in
return x+1
}
// 2. 정수형 배열의 각 요소에 2를 곱한 배열을 얻고 싶다.
arr.map { (x) -> Int in
return x*2
}
filter를 사용하여 3번을 해결해보겠습니다.
// 3. 정수형 배열에서 짝수로만 구성된 배열을 얻고 싶다.
arr.filter { (x) -> Bool in
return x%2 == 0
}
당연히 4번은 reduce의 몫입니다.
// 4. 정수형 배열 값들의 총합을 얻고 싶다.
arr.reduce(0, combine: { (result, x) -> Int in
return result + x
})
Trailing Closure 를 사용하여 다소 낯선 형태지만 코드가 너무 짧아 놀라셨죠?
(Trailing Closure는 함수의 마지막 인자가 클로져(함수)일 경우, 클로져를 함수 호출부의 꼬리(trailing)에 표기하는 방식입니다. )
이러한 고차원 함수들을 복합적으로 사용하여 프로그래밍하는 방식을 함수형 프로그래밍이라고 합니다.
함수형 프로그래밍은 짧고 명료한 코드를 작성할 수 있게하고, 버그의 가능성 또한 훨씬 줄인다고 합니다.
낯선 함수형 프로그래밍 방식에 익숙해지려면 다소 시간이 걸리겠지요? ^^
5. Map 함수 구현하기
학습한 내용을 좀더 잘 이해하기 위해 직접 map 함수를 만들어 보겠습니다.
일반적인 방법으로 1,2번 문제를 구현하는 코드를 작성했습니다.
var arr = [1, 2, 3, 4, 5]
func pluseOne(arr:[Int]) -> [Int] {
var result:[Int] = []
for x in arr {
result.append(x + 1)
}
return result
}
func multiplyTwo(arr:[Int]) -> [Int] {
var result:[Int] = []
for x in arr {
result.append(x * 2)
}
return result
}
두 함수는 연산하는 행위만 제외하고 거의 비슷합니다. 연산하는 행위를 함수로 묶어내면 일반화가 가능해보이네요.
func map(arr:[Int], transform:(Int->Int)) -> [Int] {
var result:[Int] = []
for x in arr {
result.append(transform(x))
}
return result
}
이제 제네릭을 사용하여 범용타입으로 대치하면
func map<T, U>(arr:[T], transform:(T->U)) -> [U] {
var result:[U] = []
for x in arr {
result.append(transform(x))
}
return result
}
map 함수가 완성되었습니다. 우리는 글로벌 함수로 구현했지만 표준라이브러리에서는 array의 메소드로 제공한다는 점이 유일한 차이입니다.
5. Filter 함수 구현하기
Map 함수를 구현해보아서 Filter 함수 구현은 좀더 간단합니다.
// 일반적인 방법으로 구현하고
func filter(arr:[Int]) -> [Int] {
var result:[Int] = []
for x in arr {
if x%2 == 0 {
result.append(x)
}
}
return result
}
// 함수로 공통 행위를 묶어낸 다음
func filter(arr:[Int], includeElement:(Int->Bool)) -> [Int] {
var result:[Int] = []
for x in arr {
if includeElement(x) {
result.append(x)
}
}
return result
}
// 제네릭 적용
func filter<T>(arr:[T], includeElement:(T->Bool)) -> [T] {
var result:[T] = []
for x in arr {
if includeElement(x) {
result.append(x)
}
}
return result
}
6. Reduce 함수 구현하기
단계적으로 구현해보니 고차원 함수 구현이 어렵지 않죠? 이제 reduce를 구현해 볼까요?
// 일반적으로 구현하고
func reduce(arr:[Int]) -> Int {
var result:Int = 0
for x in arr {
result = result + x
}
return result
}
// 초기값 할당과 누적하는 행위를 파라미터로 분리하고
func reduce(arr:[Int], initial:Int, combine:(Int,Int)->Int) -> Int {
var result:Int = initial
for x in arr {
result = combine(result, x)
}
return result
}
// 제네릭 적용
func reduce<T, U>(arr:[T], initial:U, combine:(U, T)->U) -> U {
var result:U = initial
for x in arr {
result = combine(result, x)
}
return result
}
지금까지 Swift 표준라이브러리의 Map, Filter, Reduce에 대해 알아보았습니다.
'Swift' 카테고리의 다른 글
| [swift2] Xcode7 beta2 Swift 언어 변경사항 (0) | 2015.06.24 |
|---|---|
| [swift] 문자열 Indexing과 Slicing (0) | 2015.06.23 |
| [swift] Map, Filter, Reduce (0) | 2015.06.22 |
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
| [swift] Apple Swift Blog (0) | 2015.06.10 |
| [swift] Swift 기초 - 4 (0) | 2014.10.29 |
설정
트랙백
댓글
글
[swift2] New in Swift2.0
올 가을 Swift2.0 정식버전이 발표된다고 합니다. Xcode7 beta Release Notes를 통해 그 변경사항을 잠시 알아볼까요?
원문: Xcode7 beta Release Notes
Swift Language Features
1. 에러처리
에러를 throw, catch 그리고 관리하는 함수를 생성할 수 있습니다. file-not-found 에러 혹은 네트워크 타임아웃
같은 회복가능한 에러를 처리하고, 의도를 명확하게 드러낼 수 있습니다. Swift 에러 처리는 NSError와 상호동작합니다.
2.가용성 체크
선택된 deployement target 보다 더 신버전의 운영체제에서 지원하는 API를 호출하면
Swift는 컴파일 타임에 에러를 보고합니다. 런타임에 영속적으로 사용 불가능한 API를 검사하려면,
if 또는 guard 문에서 새롭게 추가된 available()조건을 사용하세요.
if #available(iOS 8.0, OSX 10.10, *) {
// Use Handoff APIs when available.
let activity = NSUserActivity(activityType:"com.example.ShoppingList.view")
activity.becomeCurrent()
} else {
// Fall back when Handoff APIs not available.
}
3. @available() 속성
함수 선언부에 @available() 속성을 사용하여 가용성 정보를 명시할 수 있습니다.
// iOS 8.0 이상, OSX 10.10 이상, 다른 플랫폼의 모든 버전에서 사용가능합니다.
@available(iOS 8.0, OSX 10.10, *)
func startUserActivity() -> NSUserActivity {
...
}
4. 프로토콜 Extensions
프로토콜 타입을 위한 Extensions을 작성할 수 있습니다. 특정 프로토콜를 따르는 어떠한 타입에도 메서드와 속성을 추가
할 수 있게되어 더 많은 코드를 재사용 할수 있습니다. 유연한 인터페이스 원칙에 따라 호출 측의 dot 메서드 문법을 더 자연스럽게 하고,
제네릭 코드 정의를 더 단순하게 합니다.
5. 프로토콜 디폴트 구현
프로토콜은 프로토콜 extension 명세에 따른 기본 구현체를 가질 수 있습니다. mixin, trait 같은 패턴구현이 가능해집니다.
func xyz() throws {
6. defer 구문
defer 구문은 scope를 빠져나올때 클린업 코드를 실행합니다. 특히 새 에러처리 모델과 결합하여 사용하면 유용합니다.
let f = fopen("x.txt", "r")
defer { fclose(f) }
try foo(f) // 에러가 발생하면 f가 닫힘
let f2 = fopen("y.txt", "r")
defer { fclose(f2) }
try bar(f, f2) // 에러가 발생하면 f2가 닫히고, f가 닫힘
}
// 정상흐름에선 f2가 닫히고, 그다음 f가 닫힘
7. guard 구문
scope를 조기에 빠져나갈 수 있게합니다.
(의도하지 않는 조건에선 조기에 scope를 빠져나가게 하여, 다음 코드를 신경쓰지 않도록 해준다는 내용입니다.)
guard let z = bar() else { return }
use(z)
scope를 빠져나가기 위해 else 블럭이 필요합니다. (예를 들면 return,throw,break,continue와 함께)
8. 패턴매칭 향상
switch/case 패턴매칭이 if/case, while/case, guard/case, 그리고 for-in/case를 포함하여
많은 새로운 조건 제어구문에서 사용가능합니다. for/in 문은 where 절을 가질수 있습니다.
9. do 구문
do 구문을 사용하여 새로운 scope를 정의할수 있습니다.
do {
//new scope
do {
//another scope
}
}
10. 테스트성 향상
Swift2.0 프레임워크와 앱들의 테스트(코드)들은 내부 루틴을 public 으로 만들지 않고 작성되었습니다.
테스트 소스코드에서 모든 것을 public으로 만들어 내부 루틴을 사용할 수 있게 만들어주는 다음 구문을 사용하세요.
@testable import { ModuleName }
앱과 프레임워크 타겟은 "Enable Testability" 빌드설정을 활성화하고 컴파일 해야합니다.
Enable Testability 설정은 앱과 프레임워크의 모든 내부 심볼들까지 exporting 할지 결정하여 최적화를 막을 수 있기때문에
Debug configuration 에서만 사용되야 합니다.
11. C 함수포인터 Native 지원
함수포인터를 인자로 갖는 C함수는 clusers 또는 글로벌 함수를 사용하여 호출할 수 있습니다.
// 표준C qsort
var array = [3, 14, 15, 9, 2, 6, 5]
qsort(&array, array.count, sizeofValue(array[0])) { a, b in
return Int32(UnsafePointer<Int>(a).memory - UnsafePointer<Int>(b).memory)
}
print(array)
12. 진단기능 향상
var 대신 let 사용을 권장하기 위한 새로운 warning과 unused variables warning이 추가되었습니다.
invalid mutation warning 진다는 보다 더 정밀해졌으며, unreachable switch cases 절도 warning을
발생시킵니다.
13.enum 다중 제네릭 연관값을 지원
enum Either<T, U> {
case Left(T), Right(U)
}
13. enum 프린팅 구문 - enum case와 playload 출력 (가능한 경우에만)
@objc enum과 다중 payload를 갖는 enum 에는 적용되지 않습니다.
14. 제네릭 타입의 public extension 허용
public extension Array { … }
15. 제네릭 클래스로부터 non 제네릭 클래스 상속이 가능
16. swift 문자열 접합연산 - 컴파일 타임에 최적화를 보장
17. 실패 가능한 Convenience 생성자에서 self.init 호출전에 nil 리턴 허용
여전히 Designated 생성자들은 nil을 리턴하기 전에 모든 저장속성들을 초기화 해야합니다.
18. 중첩함수는 재귀적으로 자기자신과 다른 중첩함수들을 참조 가능
19. if 문에 라벨링 가능
라벨이 있는 break 문은 매칭되는 if문 밖으로 jump 하는데 사용됩니다.
라벨이 없는 break 문은 if문을 종료시키지 못하지만, 루프문과 스위치 구문은 종료시킵니다.
20. x? 패턴
.Some(x) 와 동일한 의미로 optional에 붙어 x? 패턴을 사용할수 있습니다.
21. 인스턴스 멤버에 @objc 키워드가 붙는 것을 방지해주는 @nonobjc 속성 추가
(Swift 코드를 Objective-C에 노출시킬 때, @nonobjc 속성이 붙은 속성과 메소드는 노출되지 않습니다.)
22. 표준 라이브러리에 readLine() 추가
'Swift' 카테고리의 다른 글
| [swift] 문자열 Indexing과 Slicing (0) | 2015.06.23 |
|---|---|
| [swift] Map, Filter, Reduce (0) | 2015.06.22 |
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
| [swift] Apple Swift Blog (0) | 2015.06.10 |
| [swift] Swift 기초 - 4 (0) | 2014.10.29 |
| [swift] Swift 기초 - 3 (1) | 2014.10.29 |
설정
트랙백
댓글
글
[swift] Apple Swift Blog
애플 WWDC 2015 에서 Swift2 공개와 올해 말 오픈소스화 발표가 있었습니다.
애플 swift 블로그를 방문하니 역시나 새롭게 단장되어있네요. Swift2 의 변화를 훑어보기 위해 대문 페이지를 번역해보았습니다.
[출처]: Apple Swift blog
Swift. 안전하고, 빠르며, 인터렉티브한
최신의 프로그래밍 언어
Swift는 iOS, OS X, watchOS를 위한 강력하고 직관적인 프로그래밍 언어입니다.
Swift 코드를 작성하는 것은 인터렉티브하고, 재미있습니다. 문법은 간결하지만 표현력이 풍부하며,
앱은 번개처럼 빠르게 실행됩니다. Swift는 당신의 다음 프로젝트 - 또는 현재 앱에도 사용할수 있도록
준비되어있습니다. - 왜냐하면 Swift는 Objective-C 와 함께 동작하기 때문이지요.
Swift 2 소개
Swift 는 밑바닥부터 개선되었습니다. 릴리즈, 디버그 빌드를 막론하고 더 빠른 코드를 생성합니다.
Swift 컴파일러는 var 대신 let를 사용하라는 새로운 Fix-it 제안을 제공해주는데도 더 빠릅니다.
주석에 마크다운를 사용하여 rich text와 내장 이미지를 추가할 수 있습니다.
새로운 assistant는 header-like 뷰에서 Swift API를 보여줍니다. 그리고 Cocoa 프레임워크와 Objective-C
코드를 더 풍부하고 훨씬 안정성있게 해주는 새로운 문법들이 개선되었습니다.
에러처리 모델(Error Handling Model)
진보된 에러처리 모델은 에러를 캐치하고 던지는 명확하고, 풍부한 문법을 제공합니다.
쉽게 커스텀 에러타입을 정의하고 명확하고 의미있는 이름으로 에러 케이스를 기술할 수 있습니다.
새로운 에러모델은 NSError 클래스와 Cocoa 프레임워크와 잘 조화되도록 설계되었습니다.
에러 처리 코드의 예입니다.
개선된 문법(Syntax improvements)
새로운 문법 특징들은 언어를 일관성 있게 개선하면서도 더 풍부한 코드를
작성할 수 있게 합니다. SDK는 Objective-C에, Swift를 더 명확하고 안전하게 하는
generics와 nullability 어노테이션을 도입했습니다.
Swift 2.0에 개선된 몇가지 예입니다.
- do, guard, defer, repeat를 사용한 강력한 제어흐름
- 함수와 메서드 키워드 네이밍 규칙 통합
- 프로토콜 extension 과 디폴트 구현
- if문과 for 루프에서의 확장된 패턴매칭
Xcode7는 애플리케이션과 playground 코드를 최신 Swift2.0 의 개선된 문법으로
변환해주는 강력한 마이그레이터를 포함합니다.
가용성(Availability)
최신의 특징, 문서, API 변경사항을 접근하기 위해서 최신의 SDK를 사용해야 했지만
때때로 앱이 더 이전 버전의 OS 에서 실행되야할 때가 있습니다.
Swift2.0은 가용성 체킹 기능을 가지고 있습니다. 이 기능은 각 target OS version 에
가장 적합한 앱을 쉽게 빌드할 수 있게 해줍니다. 컴파일러는 최소 OS 타겟에서는 지원하지 않는
새로운 api를 사용하려 할때 에러를 발생시킵니다.
그리고 특정 버전의 OS에서만 실행되도록 버전분기를 해주는 코드블럭를
랩핑하는 키워드들 제공합니다.
오픈소스(Open Source)
올해 말 Swift는 오픈소스로 릴리즈 됩니다.
우아하고, 강력하고 안전한 Swift의 결정체가 산업 전반에 소개될 수 있는
기회를 제공합니다. 우리가 함께 개발하는 것을 상상하니 흥미진진합니다.
모던(Modern)
Swift는 수십년의 애플 플랫폼 개발 경험과 가장 최신의 프로그래밍 언어 연구결과의 집합체입니다.
Objective-C에서 차용한 named 파라미터는 명확한 문법으로 표현하되, 가독성과 유지보수를 쉽게합니다.
타입추론은 모듈이 헤더를 제거하고 네임스페이스를 제공하면서, 코드를 더 깔끔하게 하고, 그리고 실수를 덜
유발하게 합니다. 메모리는 자동으로 관리되며, 세미콜론 조차 타이핑 할 필요 없습니다.
모든 이런 현대적인 아이디어들이 언어를 쉽고, 사용하기 재미있게 만들어줍니다.
Swift는 코드를 더 풍부하게 하는 다른 많은 특징들을 가지고 있습니다.
- 클로저는 함수 포인터와 통합되었습니다.
- 튜플과 다중 리턴값
- 제네릭
- 빠르고 간결한 range와 collection iteration
- 메서드, extension, 프로토콜을 지원하는 구조체
- map, filter와 같은 함수형 프로그래밍 패턴
- try/catch/throw 를 사용하는 네이티브 에러처리
| 인터렉티브 플레이그라운드 (Interactive Playgrounds) |
Playgrounds 는 Swift 코드 작성을 믿을수 없을 정도로 단순하고 재미있게 합니다.
한 줄의 코드 타이핑 결과가 즉시 나타납니다. 코드 오른편에서 빠르게 결과를 훑어보거나,
그 결과를 바로 아래에 고정할수 있습니다. 결과뷰는 그래픽, 결과리스트, 시간의 흐름에 따른 그래프로
볼수 있습니다. Time Assistant를 열어 관련된 뷰들이 변화하고 애니메이션 되는것을 볼수 있습니다.
새로운 UI코드를 실험하고, 코딩하면서 애니메이션 되는 SpriteKit Scene을 실행해보기 좋습니다.
Playground에서 코드작성을 완료했을 때, 단순히 프로젝트로 코드를 옮기세요.
Xcode7의 새로운 기능중 하나로 Playgrounds는 이탤릭 볼드, 불릿 리스트, 내장이미지와 링크 등을 가진
rich text를 사용하여 주석을 달수 있습니다. 심지어 리소스도 내장할수 있어서 코드는 단순하게 하면서도
Swift 소스 코드를 믿을수 없을 정도로 강력하고 매력적이게 할수 있습니다.
아름다운 텍스트와 인터렉티브한 코드를 사용하여 프로그래밍 커리큘럼을 공유할 수 있습니다.
새로운 알고리즘을 설계하고, 단계마다 그 결과를 볼수 있습니다.
테스트 슈트를 만들기 전에 새로운 테스트를 작성하고 동작하는지 검증할 수 있습니다.
Swift 코딩 기술을 연마하기 위해 새로운 API를 실험해볼 수 있습니다.
실험결과를 Playgrounds 안에서 동작하는 코드예제를 갖는 문서로 만들 수 있습니다.
Read-Eval-Print-Loop(REPL)
Xcode의 LLDB 디버깅 컨솔은 Swift 언어의 인터렉티브한 버전을 포함하고 있습니다.
스위프트 문법을, 실행되고 있는 앱과 상호작용하고 evaluate하는데 사용해보세요.
또 스크립트 같은 환경에서는 어떻게 동작하는지 새로운 코드를 작성해보세요.
Xcode 컨솔과 터미널에서 사용가능합니다.
안정성을 위한 설계(Designed for Safety)
Swift는 불안전한 코드들을 제거했습니다. 변수는 사용하기 전에 초기화 되어야 하고,
배열과 정수타입은 오버플로그 검사를 하며 메모리는 자동으로 관리됩니다.
문법은 의도를 잘 드러내도록 튜닝되었습니다.
예를 들어 단순하게 3문자 키워드를 사용하여 변수(var) , 상수(let)를 선언합니다.
또 다른 사례로, 디폴트로 Swift 객체는 nil이 될 수 없습니다.
Swift 컴파일러는 컴파일 타임 에러로 객체가 nil이 되는 것을 예방합니다.
이것이 코드작성을 훨씬 명확하게 하고, 안전하게 합니다. 그리고 당신 앱의 수많은 종류의
런타임 크래시들을 예방해줍니다. 그러나 nil이 유효하고 적절한 값일 경우가 있습니다.
이런 상황에서는 optional이라고 알려진 혁신적인 특징을 사용합니다.
optional은 nil을 포함할 수 있으며, Swift 문법은 당신이 이해할 수 있고, 안전하게 처리할수 있도록
?구문을 사용하도록 강제합니다.
빠르고 강력하다(Fast and Powerful)
초기 컨셉부터 Swift는 속도를 염두해두고 개발되었습니다. 고성능 LLVM 컴파일러를 사용하여, Swift 코드는
대부분의 최신 하드웨어에 최적화된 네이티브 코드로 변환됩니다. 문법과 표준라이브러리는 코드가 가장 잘 실행되도록
튜닝되었습니다.
Swift는 C와 Objective-C 언어들을 계승합니다. 로우레벨 기본형 타입들과, 제어흐름, 연산자들을 포함하고 있습니다.
클래스, 프로토콜, 제네릭과 같은 객체지향 특징들은 Cocoa, Cocoa Touch 개발자들이 필요로 하는 성능과 힘을 제공합니다.
Objective-C 상호운영성 (Interoperability) |
Swift를 사용하여 전체 애플리케이션을 작성할 수 있습니다.
현재 앱의 새로운 기능 구현을 위해서 Swift코드를 사용할 수도 있습니다.
Swift 코드는 동일 프로젝트에 있는 Objective-C 파일들과 함께 존재하며, 전체 Objective-C API 에 접근하며 쉽게 적용할
수 있습니다.
'Swift' 카테고리의 다른 글
| [swift] Map, Filter, Reduce (0) | 2015.06.22 |
|---|---|
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
| [swift] Apple Swift Blog (0) | 2015.06.10 |
| [swift] Swift 기초 - 4 (0) | 2014.10.29 |
| [swift] Swift 기초 - 3 (1) | 2014.10.29 |
| [swift] Swift 기초 - 2 (0) | 2014.10.29 |
설정
트랙백
댓글
글
[앱개발] 글 목록
설정
트랙백
댓글
글
[swift] Swift 기초 - 4
4번의 Swift 스터디 자료중 마지막 자료입니다.
지난 시간에 학습한 내용을 간단히 정리해볼까요?
구조체는 member-wise 생성자를 디폴트로 가지며, pass by value 즉 복사되어 함수에 전달됩니다.
클래스는 designated / convenience 생상자를 갖으며, pass by reference 즉 참조로 함수에 전달됩니다.
구조체,클래스의 속성으로는 저장속성, 계산속성이 있으며, 속성 옵저버에 대해 간략히 배웠습니다.
서브스크립트를 구현하면 클래스의 데이터를 인데스 문법을 사용하여 접근할 수 있습니다.
데이터 초기화 역할을 하는 생성자, 그리고 소멸자는 사용한 자원을 해제하는 역할을 담당합니다.
이번 시간에는...
사용한 객체의 참조 횟수를 추적해서, 필요없을 때 자동으로 해제해주는 ARC,
상속에 의존하지 않고 클래스를 확장할 수 있는 Extension,
Java 언어에서 인터페이스 역할을 하는 Protocol,
타입을 인자로 하여 범용타입의 자료구조를 정의할 수 있게 해주는 Generic에 대해 알아보겠습니다.
iOS5.0 부터 Objective-C에서 메모리 관리를 획기적으로 쉽게 만든 ARC는 Swift에서 기본으로 지원합니다.
Automatic Reference Counting 이라는 이름 그대로, 객체마다 참조되는 횟수를 추적하여
참조횟수가 0이 될때, 자동으로 메모리에서 해제시켜주는 기법입니다.
ARC의 동작과정을 알아보기 위해, 생성,해제 시점에 출력하는 Person 클래스를 정의하였습니다.
위 할당문 사이사이에 코드 출력문을 삽입하고, 어떤 결과가 나오는지 지켜볼까요?
Person 객체를 참조하는 변수 ref1, ref2, ref3 모두 nil이 되는 순간,
즉 레퍼런스 카운트가 0이 되는 순간 자동으로 객체가 해제되는 것을 볼 수 있습니다.
사람(Person)이 입주할 수 있는 아파트(Apartment) 클래스를 정의하였습니다.
위 코드를 실행하면 다음 결과를 출력합니다.
Person 객체의 초기화는 이루어졌지만, 해제가 되지 않았습니다. 무엇 때문일까요?
네. Apartment 객체의 tenant 속성이 Person을 참조하고 있고,
Person의 home 속성이 Apartment을 참조하고 있기 때문입니다.
이렇게 서로 참조하는 상황을 순환참조(reference cycle)라고 합니다.
순환참조가 이루어지면 메모리 해제되지 않고 남아있는 메모리 누수가 발생합니다.
Swift에서는 순환참조를 방지하기 위해 2가지 키워드를 제공합니다.
weak 키워드를 사용하면, 참조횟수를 1증가시키지 않고, 약한참조로 동작합니다.
참조하는 객체가 메모리에서 해제되면 weak 참조변수는 자동으로 nil로 초기화되어 안정성을 보장합니다.
이런 특성 때문에 optional 타입변수만 weak 참조변수가 될수 있습니다.
weak 참조는 참조 카운트를 증가시키지 않기 때문에,
renters["Elsvette"] = nil 실행과 동시에 Person 객체가 해제되고,
apts[507] = nil 의 의해 Apartment 객체가 해제됩니다.
순환참조를 방지하는 또다른 키워드는 unowned Reference 입니다.
신용카드(CreditCard)를 소유하는 고객(Customer) 클래스를 정의하였습니다.
신용카드(CreditCard) 클래스는 카드를 소유하는 고객(Customer)을 unowned 로 참조합니다.
unowned 참조는 말그대로 소유권을 갖지않는 참조로 역시 참조 카운트를 증가시키지 않습니다.
unowned 참조변수는 nil로 초기화되지 않으며, optional 타입에 사용할 수 없습니다.
unowned 참조는 보통 생명주기가 타 클래스에 의존적인 클래스에 주로 사용됩니다.
신용카드는 소유주인 고객이 존재하는 동안만 의미를 갖는다는 것을 생각해보세요.
코드 실행결과를 볼까요?
고객(Customer) 객체가 해제되고 신용카드 객체도 해제되어 순환참조 문제가 발생하지 않습니다.
정리하면, 모델링 하는 대상 클래스들의 의존성 여부와 optional 가능유무에 따라
weak와 unowned 를 구분하여 사용하면 되겠습니다!
자바에서는 인터페이스, Objective-C, Swift에서는 프토토콜 이라고 합니다.
프로토콜의 메소드는 디폴트로 required로 동작합니다.
Thing를 상속하는 Boards 클래스는 Pullable 프로토콜 메소드 pull()을
구현하지 않았기 때문에 컴파일 에러가 발생합니다.
이렇게 pull() 메소드를 구현하면 컴파일 에러가 발생하지 않습니다.
인스턴스가 프로토콜을 따르는지 유무를 알기 위해, is, as?, as! 연산자를 사용할 수 있습니다.
is는 특정 프로토콜을 따르는 경우 true, 그렇지 않으면 false를 반환합니다.
as?는 특정 프로토콜을 따르면 해당 타입으로 변환해주고, 그렇지 않으면 nil을 반환합니다.
as!는 특정 프로토콜로 강제 형변환을 시도하며, 실패할 경우 런타임 에러가 발생합니다.
Extension은 Objective-C에서 카테고리와 유사합니다.
기존에 존재하는 클래스를 변경하지 않고, (기능을) 확장할 수 있습니다.
코드의 재사용성을 획기적으로 높일 수 있는 Swift 언어의 장점 중 하나입니다.
Double 클래스를 확장하는 Extension을 만들고, 거리단위를 환산하는 메소드를 정의했습니다.
Extension 에 정의한 메소드를 활용하면, 짧고 명료한 방법으로
다양한 단위의 Double 형 부동소수값을 미터 단위로 변환할 수 있습니다.
역시 정수형 횟수만큼 특정 task 함수를 반복하는 코드를 쉽게 정의할수 있습니다.
정수형에 제곱을 구하는 Extension 메소드입니다.
Extension은 서브스크립트와도 조합하여 사용할 수 있습니다.
index에 해당하는 십진수의 자리 수를 구하는 subscript를 정의하였습니다.
문자의 자음, 모음 유무를 출력하는 Extension 메소드를 정의하였습니다.
다음과 같은 결과를 출력합니다.
제네릭은 컬렉션, 구조체, 클래스에 타입을 매개변수화하여 전달할 수 있는 기능입니다.
만일 제네릭이 없다면, 스택 데이터 구조를 정의할 때, 정수형, 문자형, 부동소수형 등 모든 타입에 대해
스택 데이터 구조를 각각 정의해야 할 것입니다.
제네릭은 타입에 대한 유연성과 안정성을 제공해주는 유용한 기능입니다.
앞서 정의한 정수형 스택에서, 타입T를 매개변수화하여 제네릭으로 정의하였습니다.
동일한 코드로, 정수형, 문자열 등 다양한 타입의 스택을 사용할 수 있습니다.
4번의 스터디를 통해 간략하게 나마 Swift 언어에 대해 훑어보았습니다.
Swift 언어는 지금도 시시각각으로 변화하고 있으며 발전하고 있습니다.
혹자는 어차피 바뀔건데 왜 벌써 공부해 ?라고 할수도 있지만, 무엇이든지 변화되는 과정을
지켜보는 것은 즐겁습니다. 그 변화 과정속에서 혹시 남들이 보지못하는 혜안을 가지게 될지 모르잖아요?
'Swift' 카테고리의 다른 글
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
|---|---|
| [swift] Apple Swift Blog (0) | 2015.06.10 |
| [swift] Swift 기초 - 4 (0) | 2014.10.29 |
| [swift] Swift 기초 - 3 (1) | 2014.10.29 |
| [swift] Swift 기초 - 2 (0) | 2014.10.29 |
| [swift] Swift 기초 - 1 (1) | 2014.10.29 |
설정
트랙백
댓글
글
[swift] Swift 기초 - 3
Swift 스터디 세 번째 시간입니다.
이번 시간에는
구조체와 클래스, 속성과 메서드,
서브스크립트와 상속, 생성자와 소멸자에 대해서 알아보겠습니다.
(생성자와 소멸자라고 번역하는게 맞는지 모르겠지만, 당분간 이 용어를 사용하겠습니다.)
클래스는 class 키워드를 사용하여 정의합니다.
신기하게도 Swift 에서는 클래스를 정의하면, 디폴트로 어떠한 클래스(NSObject와 같은...)도 상속하지 않습니다.
콜론: 을 사용하여 클래스 상속을 표현합니다.
운송수단이라는 클래스를 상속받아 자전거 클래스를 정의했습니다.
저장속성은 단순히 데이터를 담는 속성입니다.
Vehicle(운송수단) 클래스는 바퀴의 개수 저장속성과 승객수 저장속성을 가지고 있습니다.
계산속성은 저장속성을 바탕으로 계산되는 속성입니다.
자동차 클래스의 스피드 속성은 최저속도, 가속도 속성을 바탕으로
매번 계산되는 계산속성의 좋은 예입니다.
계산속성은 set, get 키워드를 사용하여 setter, getter 를 정의합니다.
운송수단 클래스에 바퀴수 저장속도를 사용하여 description 계산속성을 정의했습니다.
계산속성은 접근할 때마다 매번 가공되는(계산되는) 속성이라 할 수 있습니다.
계산속성은 선언시 반드시 타입을 정의해야 합니다.
운송수단 클래스를 사용하는 예제입니다.
멤버연산자(.dot)를 사용하여 저장속성과 계산속성에 접근합니다.
클래스는 디폴트로 init() 생성자 함수를 가지고 있습니다.
서브클래스는 생성자를 재정의(override) 할 수 있습니다.
운송수단 클래스를 상속하는 자전거 클래스는
init 생성자를 재정의하여 바퀴수를 2로 초기화합니다
계산속성은 메소드 처럼 서브클래스에서 재정의가 가능합니다.
운송수단 클래스에서 정의한 description 계산속성을
자동차 서브클래스에서 재정의하여 사용했습니다.
재정의한 계산속성을 사용하는 예제입니다.
Swift에서는 속성 옵저버를 제공하여 쉽게 옵저버 패턴을 구현할 수 있습니다.
계산속성을 정의할 때, willSet, didSet 블럭을 지정합니다.
속성이 변경되기 전, 변경된 후에 수행할 작업을 명시하면 됩니다.
willSet 블럭에서는 새롭게 변경될 속성 값을 newValue 변수로 접근할 수 있으며,
didSet 블럭에서는 변경되기 전 속성값을 oldValue 변수로 접근할 수 있습니다.
클래스의 메서드는 함수와 동일하게 func 키워드를 사용하여 클래스 내부에 정의합니다.
Swift에서 함수는 독특하게도, 내부 파라미터 이름과 외부 파라미터 이름을 갖습니다.
내부 파라미터 이름은 함수의 몸체 즉 내부에서 사용하는 이름입니다.
외부 파라미터 이름은 함수를 사용(호출)하는 곳에서 사용하는 이름입니다.
파라미터 이름 앞에 #을 사용하면 컴파일러는
내부 파라미터 이름과 외부 파라미터 이름을 동일하게 다룹니다.
각각 이름을 명시해야하는 번거로움을 피할 수 있습니다.
구조체 또한 클래스와 같이 속성과 메서드를 가질 수 있습니다.
구조체도 클래스처럼 생성자를 가지고 있습니다.
다만 구조체의 디폴트 생성자는, 파라미터 이름과 포함하고 있는 속성이름이 일치하는데,
member-wise 생성자라고 합니다.
구조체도 저장속성과 메서드를 정의할 수 있습니다.
이 시점에서 생기는 의문점!
"구조체가 속성과 메서드를 가질수 있다면 클래스와 다른게 무엇인가?"
핵심은 클래스는 참조로 전달되고, 구조체는 값이 복사 된다는 점입니다.
Window 클래스의 frame 속성을 할당한 newFrame의 속성을 변경해도, window.frame은 수정되지 않지만,
setup 함수로 전달된 window의 frame은 변경사항이 반영되는 것을 알수 있습니다.
var, let 키워드의 규칙은 기본형 뿐만 아니라 클래스, 구조체에도 일관되게 적용됩니다.
다만 조금의 차이는 있습니다.
let 으로 선언된 클래스 변수에는 다른 클래스 참조를 할당하면 컴파일 에러가 발생합니다.
let 으로 선언된 클래스 변수 자체가 상수가 됩니다.
let으로 선언된 구조체는 멤버 속성값을 변경할 수 없습니다.
즉 구조체의 멤버 속성들이 상수가 됩니다.
클래스는 참조, 구조체는 값이 복사된다는 특성을 알면 쉽게 이해할 수 있습니다.
재미있는 특성중에 하나로, 구조체의 메소드 내부에서는 속성을 변경할 수 없습니다.
속성을 수정하려면 명시적으로 mutating 키워드를 메서드 앞에 지정해야 합니다.
앞서 구조체는 member-wise 생성자를 갖는다고 이야기했습니다.
구조체도 커스텀 생성자를 정의할 수 있습니다.
다만 모든 속성은 사용하기 전에 초기화 되어야 합니다.
blue 속성을 초기화 하기 전에 validateColor() 함수를 호출하면
컴파일 에러가 발생합니다.
클래스의 모든 속성도 사용하기 전에 초기화 되어야 하는 것은 동일합니다.
모든 변수는 사용하기 전에 초기화되야 한다는 것은 Swift 언어의 공통된 규칙이지요.
기본 생성자 외에 편의상의 목적으로 조금씩 다른 여러 생성자를 정의할 수 있습니다.
Swift에서는 이런 목적의 생성자에 친절하게도 convenience 키워드를 제공합니다.
클래스 설계자의 의도대로 생성되도록 제공하는, 의도된(designated) 생성자 외에
편의성을 위해 제공하는 생성자라 생각하면 됩니다.
보통 convenience 생성자는 다른 생성자를 다시 호출하는 체이닝(chaining)을 통해 구현됩니다.
소멸자는 클래스의 메모리가 해제되는 시점에 사용한 자원을 정리하는 역할을 수행하는 함수입니다.
파일을 열어 사용했다면, 소멸자에서 파일을 닫도록 명시해 의도치 않은 메모리 누수를 막을 수 있습니다.
필요치 않은 자원을 조기부터 낭비하는 것을 막기위해,
실제 자원을 사용할때 메모리를 할당하는 레이지 로딩이라는 기법이 있습니다.
Swift에서는 속성에 lazy 키워드를 사용하여 레이지 로딩 기법을 제공합니다.
lazy로 선언된 MultiplayerManager 객체는
실제로 객체가 최초로 사용 될때(multiplayerManager.addPlayer(player) 호출 시점에) 메모리에 할당됩니다.
서브스크립트는 구조체나 클래스의 속성을 인덱스를 제공하여 접근할 수 있는 인터페이스를 제공합니다.
subscript 키워드를 사용하여, get, set 블럭을 정의합니다.
인덱스 형태로 접근하면 다루기 쉬운 특정 데이터 구조를 다룰때 편리한 문법입니다.
대표적으로 행렬을 예로 들수 있습니다.
구구단을 출력하기 위해 TimesTable 구조체에 서브스크립트를 정의하여 사용하는 예제입니다.
서브스크립트를 사용했을 때의 2가지 장점을 엿볼 수 있습니다.
첫째는 속성에 접근하는 단순화된 문법과 둘째는, 메모리 절약입니다.
3단을 출력하기 위한 모든 데이터를 저장 할 필요없이
인덱스와 단수 변수만을 사용하여 메모리를 절약했습니다.
행렬 구조체에 서브스크립트를 정의하고 있습니다.
메소드를 정의하여 똑같이 구현할수 있는 기능이지만
서브스크립트를 사용하면 쉽고 가독성이 좋습니다.
'Swift' 카테고리의 다른 글
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
|---|---|
| [swift] Apple Swift Blog (0) | 2015.06.10 |
| [swift] Swift 기초 - 4 (0) | 2014.10.29 |
| [swift] Swift 기초 - 3 (1) | 2014.10.29 |
| [swift] Swift 기초 - 2 (0) | 2014.10.29 |
| [swift] Swift 기초 - 1 (1) | 2014.10.29 |
설정
트랙백
댓글
글
[swift] Swift 기초 - 2
Swift 두 번째 스터디입니다.
지난 시간에 학습한 내용을 정리해볼까요?
1. 변수 선언은 var 키워드를, 상수 선언은 let 키워드를 사용합니다.
2. Swift 컴파일러는 변수에 할당되는 값을 통해 타입을 추론합니다.
3. 유니코드에서 지원하는 다양한 문자를 변수 이름에 사용할 수 있습니다.
4. 문자열 타입 String, 문자 타입 Character를 지원합니다.
5. Array, Dictionary 컬렉션의 요소들은 동일한 타입이어야 합니다.
4. foreach 구문을 사용할 수 있고, for-range 루프 문을 지원합니다.
5. Switch-Case 문에 정수형 이외의 타입도 사용 가능합니다.
6. Swift의 모든 변수는 디폴트로 nil이 할당 될 수 없습니다.
7. nil 이 될수 있는 변수는 ? 연산자를 붙혀 optional 타입으로 선언합니다.
8. optional 변수는 사용하기 전에 !연산자를 사용하여 unwrapping 해야 합니다.
이번 시간에는 함수, 클로져, 그리고 enum 타입에 대해 알아보겠습니다.
optional 에 대해 다시한번 정리하고 갈까요?
optional 타입은 런타임에 발생할 수 있는 nil 에러를
컴파일 타임에 발견할 수 있도록 해줍니다.
보다 안전한 프로그램을 개발할 수 있도록 Swift 언어에서 제공하는 키워드이지요.
회사이름을 인자로 받아 주식코드를 반환하는 Objective-C 코드 예제입니다.
Facebook 에 대한 주식코드는 정의되지 않았기 때문에 마지막 라인의 코드에서
text 문자열에 nil을 추가하려고 하여 런타임 에러가 발생하는 코드입니다.
문법적으로는 유효한 구문이기 때문에
이 에러는 실제 프로그램이 실행되기 전까지 문제를 알 수 없습니다. 헉!
Swift에서는 optional 타입을 도입하여 이 문제를 멋지게 해결합니다.
nil이 될수 있는 변수는 optional 타입으로 선언하도록 강제한 것이지요.
"optional 타입"은 " nil이 될수 있으니 주의깊게 다루세요" 라고 말하는 것과 같습니다.
위 Swift 코드에서는 컴파일러가 컴파일 타임에 에러를 알려 줍니다. 굿!
optional 타입을 사용하기 전에는 반드시 옵셔널 타입을 상쇄해야 하는데, unwrapping 한다고 표현합니다.
unwrapping 하는 방법은 if 문을 사용하여 nil 이 경우에, ! 연산자를 사용하여 optional을 상쇄합니다.
if 문을 사용하는 이유는, nil 인 경우에 !연산자를 사용하면 런타임 에러가 발생하기 때문입니다.
nil이 아니라는 것을 보장하는 경우에 unwrapping해서 사용하라는 의미이지요.
이 구문은 swift에서 관용구 처럼 사용되는데, optional binding이라하는 좀더 세련된 방법을 제공합니다.
정확히 이전 구문예제와 동일한 역할을 하는 optional binding 구문입니다.
! 연산자 대신에 let 상수 키워드를 사용하여 unwrapping하는 것이 유일한 차이입니다.
자주 사용하게 될 구문이니 꼭 기억하세요.
함수 자체를 if 평가문에 사용하여 unwrapping 할수도 있습니다.
Swift에서는 func 키워드를 사용하여 함수를 정의합니다.
함수의 파라미터에 디폴트 값을 지정 할 수 있습니다.
buildGreeting()과 같이 인자없이 호출할 경우 name 파라미터에 "World" 문자열이 할당되어 사용됩니다.
튜플 타입을 지원합니다. 튜플은 쉽게 말하면 값의 묶음이라 할수 있습니다.
튜플은 선언과 동시에 상수가 되며, 값을 변경하려고 할 경우 컴파일 에러가 발생합니다.
튜플을 사용하면 한 번에 여러값을 전달하고, 반환할 수 있어서 편리합니다.
반환된 튜플을 어떻게 사용해야 할까요? 튜플 변수에 값을 할당하여 사용할 수 있습니다.
반환되는 튜플의 원소에 이름을 부여하여 사용할 수도 있습니다.
클로져는 쉽게 말해 실행가능한 코드블럭이라 할수 있습니다.
함수도 코드 블럭이기 때문에 클로져로 사용할 수 있습니다.
이 클로져를 변수에 할당해 두고 필요한 때에 호출해서 사용할 수 있습니다.
클로져는 파라미터와 반환하는 값, 그리고 코드 블럭으로 구성됩니다.
greetingPrinter는 파라미터와 반환값 없이, "Hello World!" 를 출력하는 클로져 입니다.
클로져의 재미있는 점은 함수의 인자 혹은 반환값으로 사용할 수 있다는 점입니다.
파라미터,반환값으로 정적인 데이터 뿐만이 아니라 동적인 행동(코드블럭)을
전달하여, 다양한 조합으로 사용할 수 있습니다.
위 코드는 코드블럭을 특정 횟수만큼 반복하는 클로져의 예입니다.
클로져가 마지막 파라미터 인 경우
위와 같이 함수의 꼬리에 클로져가 따라오는 형태로 사용할 수 있는데,
이런 형태를 Trailing 클로져라고 합니다.
Swift의 enum은 연관된 값을 전달하여 사용할 수 있습니다.
switch-case 문과 조합하여 유용하게 사용할 수 있는데, 자세한 설명은 나중으로 미루겠습니다.
Int 타입으로 정의한 Planet enum 변수를 println() 함수로 출력하면
엉뚱하게도 Enum Value 라는 값이 출력됩니다. enum이 갖는 값이 아닌 enum 자체가 출력되는 것입니다.
enum 의 원소값을 출력하고 싶을 때는, enum.toRaw() 멤버함수를 사용합니다.
enum 타입을 정수가 아닌 문자형으로 정의하여 원소값을 출력하는 예입니다.
나중에 클래스와 구조체에 대해 알아보겠지만
enum 도 초기화함수(생성자)와 멤버함수를 갖을 수 있습니다.
enum 을 생성하고 멤버함수를 호출하는 예입니다.
'Swift' 카테고리의 다른 글
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
|---|---|
| [swift] Apple Swift Blog (0) | 2015.06.10 |
| [swift] Swift 기초 - 4 (0) | 2014.10.29 |
| [swift] Swift 기초 - 3 (1) | 2014.10.29 |
| [swift] Swift 기초 - 2 (0) | 2014.10.29 |
| [swift] Swift 기초 - 1 (1) | 2014.10.29 |
설정
트랙백
댓글
글
[swift] Swift 기초 - 1
"Swift는 어떤 언어인가? 애플은 왜 Swift 언어를 만들었을까? "
"Objective-C 언어를 대체할 새로운 언어인가? Objective-C 언어는 사라지는건가?"
"그렇게 되기까지 어느 정도의 시간이 걸릴 것인가?"
위 질문들에 답을 찾기 위해 시작한 스터디(총 4강)의 결과물을 공유합니다.
Swift는 iOS, OSX 개발을 위해 애플에서 발표한
멀티 패러타임, 컴파일 프로그래밍 언어입니다.
2014 WWDC에서 처음 소개되었고, 코코아/코코아 터치,
Objective-C 코드와 호환되게 설계되었습니다.
2014 WWDC에서 크레이그 페더릭은 "Objective-C가 없는 C언어"라고 소개하였습니다.
C언어처럼 빠르면서 Objective-C 언어의 생산성과 강력함을 가진 언어!
애플 개발자 Swift 공식 사이트에서는 코드작성이 인터렉티브하고,
재미있고, 혁명적인 새로운 프로그래밍 언어라고 소개합니다.
Swift 단어의 뜻을 아시나요?
제비를 닮은 심볼은 해안과 산지의 바위절벽에 서식하며
여름에 우리나라에 찾아온다는 "칼새"를 의미합니다.
"신속한","빠른" 이라는 뜻도 동시에 가지고 있지요
Swift의 심볼이 정말 칼새와 똑같이 생겼네요.
Swift는 현대 프로그래밍 언어의 장점을 두루 채용한 언어입니다.
주요 스펙은 기존의 서버사이드 병렬 스크립트 swift 언어에서 가져와,
다른 특징들을 결합했다고 합니다.
Swift를 3단어로 표현하면 - SAFE! MORDERN! POWER!
2010년 애플 개발툴 부서 총책임자 "크리스 레트너"에 의해
Swift 프로젝트가 시작되었습니다. 이후 많은 개발자들의 참여로 발전하게 되었고,
오늘에 이르게 되었습니다. Swift의 아버지 = 크리스 레트너?
새롭게 소개된 Xcode6에는 Swift 코드를 인터랙티브하게 실험해볼 수 있는
Playground 라는 템플릿을 포함하고 있습니다.
컨솔출력뿐만 아니라 UI 요소들 또한 바로 확인할 수 있으며
루프문의 값을 기억해 그래프로 그려주기까지 합니다.
코드를 맘껏 가지고 놀 수 있는 놀이터 그 자체입니다.
이제부터 Swift의 문법에 대해서 알아보겠습니다.
가장 기초가 되는 변수와 상수는 어떻게 선언할까요?
변수는 var, 상수는 let 키워드를 사용합니다.
정수,실수,문자열,배열,사전,클래스 등 모든 타입들에 적용되는
일관되면서 심플한 규칙을 따릅니다.
(편리성을 위해 3문자 키워드로 맞추는 섬세함까지!)
Swift의 두드러진 특징 중의 하나로 타입추론을 꼽을 수 있습니다.
타입추론이란 할당되는 값(Value)을 통해 변수의 타입을 예측하는 것을 의미합니다.
똑똑한 컴파일러는 변수에 타입을 명시하지 않아도 할당되는 값을 보고
이 변수가 "Int 혹은 String" 타입으로 예측하고 이후부터 해당타입으로 변수를 취급합니다.
Swift는 유니코드문자를 변수이름으로 사용할 수 있습니다.
이모티콘으로도 변수이름을 지을 수 있으니 재미있을 따름입니다.
"" 쌍타옴표로 감싼 문자열을 String 타입으로 인식합니다.
Objective-C와는 다르게 문자열을 표기하는데 @를 사용하지 않지요.
for-each 구문을 사용해서 문자열(String)을
이루는 문자(Character)를 간편하게 순회할수 있습니다.
스터디를 진행했던 Xcode6 Beta 베타 버전에서는
문자+문자, 문자열+문자 의 접합연산이 가능했는데,
Swift1.0 정식버전에서는 불가능해졌습니다.
배열과 배열, 문자열과 문자열의 접합연산만이 가능다는 점! 주의하세요
포맷팅 문자열은 어떻게 만들까요?
문자열 내부에 \(변수) 구문을 사용해서 원하는 값으로 치환이 가능합니다.
앞서 언급했던 Swift의 간결함 중 한 가지! 기억하나요?
var 키워드를 사용하면 수정 가능한 문자열.
let 키워드를 사용하면 수정 불가능한 문장열을 정의할 수 있습니다.
Array와 Dictionary에 대해서 알아볼까요?
Objective-C의 NSArray, NSDictionary와 대응하는 클래스로, 대괄호[]를 사용하여 선언합니다.
Array는 값의 순서리스트를,
Dictionary는 키:값 쌍으로 초기화 할 수 있습니다.
Objective-C에서는 NSObject를 상속하는 어떤클래스도 포함할 수 있었습니다.
반면 Swift에서는 Array는 동일한 타입의 값들만 포함할 수 있고,
Dictionary는 문자열 키에 동일한 타입의 값들만 포함해야한다는 제약이 추가되었습니다.
일반적인 while과 for 루프문을 사용할 수 있습니다.
루프 조건문에서는 ()를 사용할 수 있지만 일반적으로 사용하지 않는게 관례입니다.
Objective-C에서는 볼수 없었던 Range 루프문입니다.
1...5는 1부터 5를 포함하여 5번의 루프를,
0..<5는 0부터 5를 포함하지 않고 5번의 루프를 반복합니다.
(마치 for 조건문에 i < 5와 i <= 5 를 사용하는 것처럼)
for-each 구문으로 Array를 순회할 수 있습니다.
Dictionary도 아직 배우지 않았지만 튜플을 사용하여 (키,값)쌍으로 순회할 수 있습니다.
Swift의 변수는 디폴트로 nil이 될수 없습니다.
즉 선언과 동시에 반드시 초기화가 이루어져야 하지요.
null 과 같이 아직 값을 갖지 않는 변수가 필요할 때는 어떻할까요?
그래서 필요한 것이 Optional 타입입니다. 변수의 타입 뒤에 ?를 붙여 옵셔널 타입으로
선언하면, 변수는 nil (null)값을 가질 수 있습니다.
"optional 타입" 의 자세한 내용은 다음 강의에서 설명하겠습니다.
Optional로 선언된 변수는 그냥 사용할 수 없습니다.
컴파일 에러에서 벗어나기 위해 optional 타입을 벗겨야(unwrapping) 하는데요
위와 같은 구문을 사용해서 optional 타입을 unwrapping 할 수 있습니다.
"possibleLegCount가 nil 아니면 그 값을 상수 letCount에 할당하고 if 문으로.."
처럼 해석할 수 있습니다. 역시 자세한 설명은 다음 강의에서.
switch 구문입니다. Objective-C와 다른 점을 눈치 채셨나요?
그렇습니다. case 조건안에 ,를 구분으로 여러 값을 명시할 수 있습니다.
또 switch 문에 정수형 외에 다른 타입들도 사용이 가능합니다.
1강 끝~~ 이라고 하기엔 아직 이릅니다. 아래를 보세요.
2014 WWDC 가 진행되면서 앱스토어에
WWDC 세션을 소개하고 안내하는 Swift 최초의 공식앱이 올라왔습니다.
iOS8과 요세미티를 deployment target으로 한 앱은 미래에도 정상작동을 보장합니다.
사실 메버릭스와 iOS7을 타겟으로 해도 동작하는데 그 이유는
앱 번들 안에 경량의 swift 런타임을 포함하기 때문이라고 합니다.
Swift 스펙이 안정화될 즈음에 런타임이 제거될거라 합니다.
바이너리 호환성은 보장되지 않는다고 하니, 앱의 모든 컴포넌트들은
동일한 버전의 Xcode와 Swift 컴파일러를 사용해서 빌드되야 합니다.
Swift의 스펙은 아직도 핫하게 변경되고 있어서 소스코드 수준의 호환성을
보장하지 않습니다. Xcode에서 마이그레이션 할 수 있는 수단을 제공할 계획이라고 합니다.
호환성 문제가 있긴 하지만, Swift가 기존 플랫폼에서도 실행가능한 이유는
Objective-C와 동일한 런타임을 사용하기 때문이라고 하네요
단일 프로그램에서 함께 복합해서 사용할 수도 있구요
브리징 헤더를 제공하면 Objective-C로 작성된 코드를 Swift에서도 손쉽게 사용할 수 있습니다.
Optional 타입은 왜 필요한가? 에 대한 의문이 생깁니다.
컴파일 타입에 확정된 값을 갖지 않는 변수에 사용한다면,
대다수의 변수들이 optional로 선언되어야 할텐데, 왜 굳이 옵셔널 타입이 필요한 걸까요??
자세한 내용은 다음 강의에서!
위 구문은 어떤 결과를 갖을까요?
첫번째 구문은 nil 값을 갖는 상수입니다.
상수이기 떼문에 당연히 값을 변경하고자 하면 에러가 발생하겠지요
아래 구문은 옵셔널 타입이 아니기 때문에 nil을 할당할 수 없습니다.
'Swift' 카테고리의 다른 글
| [swift2] New in Swift2.0 (0) | 2015.06.19 |
|---|---|
| [swift] Apple Swift Blog (0) | 2015.06.10 |
| [swift] Swift 기초 - 4 (0) | 2014.10.29 |
| [swift] Swift 기초 - 3 (1) | 2014.10.29 |
| [swift] Swift 기초 - 2 (0) | 2014.10.29 |
| [swift] Swift 기초 - 1 (1) | 2014.10.29 |
설정
트랙백
댓글
-
파운데이션 2015.01.26 20:14
정말 좋은 글입니다 감사합니다
글
[Xcode] 지원 시뮬레이터 목록을 출력하는 명령
터미널에서 다음 명령을 사용해서
Xcode에서 지원하는 시뮬레이터 목록을 얻어올 수 있습니다.
시뮬레이터에서 테스트를 위해
앱번들 폴더를 알고 싶을 때 도움되는 명령이지요 ~
xcrun simctl list
'개발도구로그' 카테고리의 다른 글
| [Xcode] 지원 시뮬레이터 목록을 출력하는 명령 (0) | 2014.10.20 |
|---|---|
| [Vi] Vi 사용하기 (0) | 2011.04.25 |
| [SVN] Subversion 명령들 (0) | 2011.03.18 |
| visual studio2008 에서 커스텀 헤더파일과 라이브러리 포함시키기 (0) | 2011.02.13 |
| [VC2008] 라인넘버 표시 (0) | 2010.12.13 |
| [VC2008] 문자 셋 변경 (0) | 2010.12.13 |
설정
트랙백
댓글
글
서른살에 알았더라면 좋았을 것들
(앞으로 인생을 고민하는 당신에게)
서른살에 알았더라면 좋았을 것들
1. 서른, 지금이 시작할 때
2. 일 외에 좋아하는 것에 몰입하라
- 우리 인생의 트라이 앵글
- 개인 시간을 가지면 열정이 솟아난다
- '공 사 개'가 가진 상승효과
- 좋아하는 일을 꾸준히 한다
- 라이프워크는 변해도 상관없다
- 주제를 정하면 세계가 넓어진다
- 개인 시간을 확보하는 방법
- 하루 일과 속 '공 사 개'를 생각한다
- 일주일 속 '공 사 개'를 생각한다
3. 보이지 않는 것도 봐라
- 젊은 시절에는 '보이지 않는다'
- 전망이 좋은 위치로 가라
- 두 단계 위의 입장에서 생각한다
- 전체 최적을 파악하고 일을 한다
4. 소신 있게 판단하고 책임져라
- 신속하게 결정하고 즉시 시작하라
- 어느 쪽을 택하든 최선을 다한다
- '다른 사람과 의논하지 않을' 용기
- 진심으로 하는 사람은 누구도 막을 수 없다
5. 미친듯이 맹렬하게 일하라
- 현대 비즈니스맨의 이상형 : 2시간 단위의 시간 활용법
- 성공은 천천히, 기회는 갑자기 온다
- 삼십 대엔 노도의 업무량을 해치워라 : "죽을 각오를 하고 덤벼서 죽은 사람은 없다. 자신을 버리고 필사의 의지로 노력하면 만사가 순조롭게 풀린다"
- 죽기 살기로 일하라 : "죽기 살기로 노력한 사람에게만 보이는 세계가 있다"
<팔물훈> - 와나타베 가잔
: 큰 콩은 천천히 오고 기회는 급작스럽게 온다는 사실을 잊지 마라
=> 평소에 끊임없이 단련하고 학문에 힘쓰며 부단히 관찰하다 보면 큰 성공으로 이어진다
: 전면의 공을 기하고 후면의 비를 잊지 마라
=> 눈앞의 이익에 현혹되면 일을 그르칠 우려가 있다
: 자기 전에 백년지계를 잊지마라
=> 지금 현재 먹고사는데 급급해 장기적인 전망을 잊어서는 안 된다
6. 다른 세계로의 여행을 즐겨라
- 소년의 마음으로 여행을 떠나라
- 이질과의 조우가 자신을 성장시킨다
- 다른 세대의 친구와도 교류하라
7. 최선을 다하면 다른 길이 열린다
- 요구받은 일에 전력투구하라
- 이직하고 싶으면 이직하지 마라
- '4가지 자유'로 이직을 고려하라
8. 시간을 통제하는 사람이 돼라
- '시간 주권'을 확립하라
- 내 업무 스케줄이 우선이다
- 시간 주권을 확대하는 방법
9. 또 다른 성장기, 서른의 공부법
- 비즈니스맨의 공부법
- 의의 있는 자격증 취득법
- 프로의 정보를 얻어라
- 트위터를 활용해 영어를 공부한다
- 신문의 가치를 발견한다
- 배움으로 이어지는 독서법
10. 자기 계발이 곧 저축이다
- 저금보다 자기 계발에 힘써라
- 돈에 여유가 있는 사람은 많지 않다
- 4분의 1 공제 저금법
- '경제적 자유'를 위해 준비하라
11. 서른의 건강은 미래를 위한 투자
- 자신에게 '건강'을 선물한다
- 의식적으로 꾸준히 운동하라
- 몸이 건강해야 마음도 건강하다
- 일기나 블로그에 기록을 남겨라
12. 인간관계에 능한 사람이 돼라
- 인간관계 고민 해결을 위한 에니어그램
- 9가지 성격 유형과 적합한 직업
- 상대방의 성격 유형을 파악하라
- 성격이라는 기본 소프트웨어
- 다양한 관계를 맺는 열쇠
13. 삼심 대의 인맥이 미래의 재산
- '커뮤니케이션의 회로'를 열어둔다
- 출세해도 절대 거드름을 피우지 않는다
- 인맥 지도를 만들고 활용한다
- 잘나가는 사람을 친구로 삼자
- 가족이 생기면 더 성장한다
- 스스로 좋은 배우자를 찾아 나서라
14. 성공의 힘은 재능이 아니라 끈기
- '목표 설정형'과 '적립형'
- 평범한 사람은 노력하는 수밖에 없다
- 포기하지 않고 노력하는 끈기의 힘
'생각로그' 카테고리의 다른 글
| 서른살에 알았더라면 좋았을 것들 (0) | 2014.04.24 |
|---|---|
| [시] 지금 하십시오 (0) | 2014.01.09 |
| 시간정리 (1) | 2012.05.21 |
| Ignite 분당에 참석하고 나서... (4) | 2012.05.19 |
| [마인드맵]C언어의 역사 (0) | 2012.03.05 |
| 성공하는 말하기 (0) | 2012.03.01 |