[SSAC - iOS] 09월 30일 TIL

[SSAC - iOS] 09월 30일 TIL

오늘 수업은 문법 위주로 진행하였다.

알고 있는 것도 있었고, 애매하게 아는 것도 있어서 열심히 들었다.

TIL에 들어가는 사진들은 멘토님께서 정성스럽게 직접 만드신거다..

잘 참고해서 쓰겠습니다..!!!!!

2021.08.02 - [Swift 문법 정리 - iOS] - [Swift] 클래스 VS 구조체 / 열거형

2021.08.02 - [Swift 문법 정리 - iOS] - [Swift] 인스턴스 / 프로퍼티 / 메서드

2021.07.27 - [Swift 문법 정리 - iOS] - [Swift] 스위프트 기초 문법

이전에 변수와 상수에 대해 정리해 놓은 글이 있어서 구체적으로 정리하지는 않겠습니다!

선언과 초기화

변수와 상수는 먼저 선언을 해야 사용 가능

선언하는 키워드는 변수일 경우네는 var, 상수일 경우에는 let

선언된 변수와 상수에 처음으로 값을 대입하는 것이 초기화 !

변수를 쓸 지, 상수를 쓸 지 정한다. 값을 담을 공간의 이름을 작성한다. 값을 대입(할당)한다.

타입 어노테이션과 타입 추론

타입 추론

누가 봐도! 타입이 명확한 경우에는 컴파일러가 자동으로 타입을 인식할 수 있기 때문에 타입 선언을 생략할 수 있다.

하지만 원하는 타입을 꼭 명시해야 할 때 혹은 애매한 경우에는 타입 선언이 필요하다.

// 학점이라는 변수에 4라고 입력했다가 4.5로 변경하고 싶은 경우, Double 혹은 Float으로 선언하지 않으면 Int로 자동 인식되기 때문에 4.5를 입력한 경우 에러 발생 -> 이를 명확하게 명시해주는 부분이 타입어노테이션 // 타입 어노테이션 var num1 = 4 var num2 : Float = 4 print(num1) // 4 print(num2) // 4.0 // 타입 추론 var userID = "hello" // var userID : String = "hello" 에서 : String 생략 var age = 44 // var age : Int = 44 에서 : Int 생략

기본 자료형

멘토님이 직접 그려가며 설명을 해주셨는데 이해가 잘 갔던 부분이다.

이 부분도 위에 스위프트 기초 문법에서 정리를 해놓았으니 참고하면 좋겠다.

따라서 자료에서 한 번 더 짚고 넘어가고 싶은 부분만 정리하겠다.

오류 대처법

// 타입이 다른 경우, 변수를 사용하고 있더라도 값을 변경할 수 없음 -> 알맞은 타입으로 조절하거나, 형변환을 통해 해결할 수 있음 var rate = 4 rate = 3.5 -> 에러 발생

// 변수명 혹은 상수명을 중복으로 설정한 경우, 구별하기가 어려워져 에러 발생 -> 똑같은 변수명을 재선언하지 않도록 변수명 혹은 상수명 수정으로 해결 var gameLevel : Int = 6 var gameLevle : Int = 3 -> 에러 발생

// 변수를 사용했지만 값 변경이 이루어지지 않았을 때 상수를 사용해도 무방한 부분이라고 권장하는 부분 -> 상수를 바꾸어주며 해결 var luckyNumber = Int.random(in: 1...100) pront(luckNumber)

상수를 사용해도 무방한 부분이라 var을 let으로 바꿔달라는 에러

// 변수 혹은 상수를 선언한 뒤, 코드 내부에서 사용하지 않을 경우 -> 변수 / 상수명을 _(언더바)를 통해 사용하지 않도록 하거나 값ㅇ르 확인해보는 print 등의 방법으로 해결 var userName = "고래밥"

Xcode에서 자주 봤던 에러인데.. 맨날 Fix만 누르고 그냥 넘어갔었는데 왜 이런 에러가 발생하는지에 대해 알게 되었음.

// : 과 = 의 역할은 다름 -> 타입을 선언할 때는 :, 값을 넣어줄 때는 = 를 사용

Array

Array에 관한 부분도 스위프트 기초 문법에서 다뤄서 요 부분도 간단하게 정리하겠다.

같은 타입의 데이터

순서대로 정렬 (인덱스)

언제든지 데이터 수정, 삭제, 추가 등을 할 수 있음

빈 값이 초기화 되어 있을 경우 -> 어떤 타입의 배열인지 알 수 없기 때문에 타입 어노테이션을 통해

배열이 어떤 타입을 담고 있는지 선언해야 함.

var weekend = [] -> error var weekend : [String] = []

Dictionary

고유한 키(Key)와 키에 해당하는 값(Value)으로 구성 Key에 Value가 종속되어 있다. 즉, Key를 삭제하면 Value도 모두 사라진다.

Set

수학의 집합과 동일한 특성을 지님 (교집합, 합집합 등의 관계 표현 가능) 값들은 중복될 수 없다. 집합을 사용할 때는, 무조건 Set 타입임을 명시해주어야 한다.(타입 어노테이션) 그렇지 않을 경우, 배열로 타입추론한다.

Tuple

다른 타입을 담을 수 있는 특별한 자료형 어떤 형태든 마음대로 만들 수 있음. 인덱스가 존재함. 즉, 순서가 있다. 한 번 선언되면, 수정과 삭제가 불가능

+++ Mission

Type Alias (타입 별칭)

Type Alias는 코드를 조금 더 간결하게, 가독성있게 작성하기 위해 사용한다.

- 타입에 붙일 수 있는 별칭, 약칭이다.

typealias (사용할 별명) = (존재하는 타입) // 예시 typalias nickName = Int typealias Codable = Decodable & Encodable

새로운 타입을 만드는 것이 아니라 기존 유형을 새로운 이름으로 부를 수 있게 만드는 것이다.

1) 프로토콜의 결합

프로토콜을 결합하는 경우 사용할 수 있다.

struct DataModel: Codable { var name: String var description: String } public typealias Codable = Decodable & Encodable

2) 기본 유형에 의미 추가

func heatProduced() -> Double { return 0 } typealias Jules = Double func heatProduced() -> Jules { return 0 }

3) 제네릭 유형에 사용

typealias EventList = Array let array:EventList = EventList(arrayLiteral: 1,2,3) typealias EventList = Array where T:StringProtocol

4) 클로저에 사용

import Foundation import Alamofire class APIClient { typealias onSuccess = ((T) -> Void) typealias onFailure = ((_ error: Error) -> Void) static func request(_ object: T.Type, router: APIRouter, success: @escaping onSuccess, failure: @escaping onFailure) where T: Decodable { AF.request(router) .validate(statusCode: 200..<500) .responseDecodable(of: object) { response in switch response.result { case .success: guard let decodedData = response.value else { return } success(decodedData) case .failure(let err): failure(err) } } } }

5) 프로토콜의 관련 타입 (AssociatedType)

protocol Example { associatedtype load: StringProtocol } struct Implement: Example { typealias load = String }

6) 프로토콜 선언 시

protocol Sequence { associatedtype Iterator: IteratorProtocol typealias Element = Iterator.Element } func sum(_ sequence: T) -> Int where T.Element == Int { // ... } // typealias가 없었다면 T.Iterator.Element로 사용해야 하지만 // typealias로 T.Element로 짧게 사용할 수 있다.

taekki님 블로그 글을 보았을 때 정말 설명을 잘 해주셔서,, 이 부분은 이해하고 더 공부를 해봐야 할 것 같습니다.

클로저, 서버 통신 코드를 작성할 때에 유용하게 사용 가능하다고 taekki님께서 말씀해주셨네요!

Generic

Genericd을 사용하면, 유연하고 재사용성 높은 코드를 작성할 수 있다고 한다.

Apple이 말하길..

"Generic은 Swift의 가장 강력한 도구 중 하나이다.

Swift 표준 라이브러리는 대부분 Generic으로 작성되어있다.

실제로, 내가 Generic을 사용했다는 것을 인식 못했다고 해도, 이때까지 쭉 사용해왔다!

예시로 Array, Dictionary이 있다."

예시를 살펴보면

func swapTwoInts(_ a: inout Int, _b: inout Int) { let temporaryA = a a = b b = temporaryA }

두 정수의 값을 바꿔주는 함수가 있다.

func swapTwoInts(_ a: inout Int, _b: inout Int) { let temporaryA = a a = b b = temporaryA } var a = 0.0 var b = 1.0 swapTowInts(&a;, &b;)

하지만 파라미터에 Double형을 넣으면 에러가 발생한다.

swapToInts의 파라미터는 Int형이기 때문이다.

그래서 Double형 바꿔주는 함수 하나 더 만들지!

func swapTwoInts(_ a: inout Double, _b: inout Double) { let temporaryA = a a = b b = temporaryA }

결국 똑같은 일을 하는데, 타입마다 따로 함수를 만들어야 하니 불편하다..

바로 이 때, Generic을 사용한다.

func swapTwoValues(_ a: inout T, _b: inout T) { let temporaryA = a a = b b = temporaryA }

이렇게만 해주면, 이 함수 하나로 Int, String, Double 변수들의 값을 바꿔줄 수 있다! (둘 다 같은 타입일때만)

코드를 살펴보면 함수 이름 옆에 가 있다. 그리고 swapTwoValues의 파라미터 자리에, 타입이 들어갈 부분에 T라는 것이 있다.

여기서 T는 타입 파라미터라고 불린다.

파라미터 부분에 들어간 T는 Placeholder 타입 "이름"이다.

String, Int도 "이름"인 것 처럼 T라는 타입의 "이름"이 들어간 것이다.

이 T는 swapTwoValues라는 함수가 호출될 때마다 "결정"된다.

*a와 b는 이 T타입과 반드시 일치해야한다!

그리고 함수 옆에 적힌

Generic함수와 일반함수의 가장 큰 차이점이다.

Generic함수는 함수 이름 옆에, 위에서 말한 Placeholder 타입 이름이 온다.

대괄호(<>)로 묶어준 이유는,

Swift에게 함수 정의 내의 Placeholder 타입 이름이라는 것을 알린다.

"T"는 Placeholder이므로, Swift는 "T"라는 실제 타입을 찾지 않는다.

제드님의 블로그를 참고하고 작성하였습니다..

정말 이해하기 쉽게 설명을 해주셔서 감사합니다....!!!!!

삼항 연산자

삼항연산자도 최근에 정리해둔 포스트가 있어서 따로 정리하지 않겠습니다..!

2021.09.26 - [[Swift] 이것저것] - [Swift] 화면 간 데이터 전달 (삼항 연산자, if - let 옵셔널 바인딩) [1/2]

사실 오늘 배운 것들이 너무 많아서 하나씩 적용을 하고 습득하기까지 정말 오래 걸릴 것 같다..

꾸준히 화이팅..!!!

출처 (ㄱㅅㅎㄴㄷ)

https://taekki-dev.tistory.com/33

https://zeddios.tistory.com/226

from http://seungchan.tistory.com/58 by ccl(A) rewrite - 2021-09-30 20:00:27