Swift
[Swift] 익스텐션(Extension)
💡익스텐션 (Extension) 익스텐션은 스위프트의 강력한 기능 중 하나로 구조체, 클래스, 열거형, 프로토콜 타입에 새로운 기능을 추가할 수 있습니다. 기능을 추가하려는 타입을 구현한 소스 코드를 알지 못하거나 볼 수 없다 해도, 타입만 안다면 그 타입의 기능을 확장할 수도 있습니다. 📍스위프트의 익스텐션이 타입에 추가할 수 있는 기능 연산 타입 프로퍼티 / 연산 인스턴스 프로퍼티 타입 메서드 / 인스턴스 메서드 이니셜라이저 서브스크립트 중첩 타입 특정 프로토콜을 준수할 수 있도록 기능 추가 ⭐️익스텐션은 타입에 새로운 기능을 추가할 수는 있지만, 기존에 존재하는 기능을 재정의할 수는 없습니다. 🔥 상속 VS 익스텐션 상속 익스텐션 확장 수직 확장 수평 확장 사용 클래스 타입에서만 사용 클래스, 구조..
[Swift] 프로토콜(Protocol)
💡프로토콜 (Protocol) 프로토콜은 특정 역할을 수행하기 위한 메서드, 프로퍼티, 기타 요구사항 등의 청사진을 정의합니다. 쉽게 말하자면 어떤 타입(클래스, 구조체 등등)이 특정 기능이 필요해서 이 기능을 꼭 구현해야 한다고 강요하는 것과 같습니다. 이러한 구조체, 클래스, 열거형은 프로토콜을 채택해서 프로토콜의 요구사항을 실제로 구현할 수 있습니다. 어떤 프로토콜의 요구사항을 모두 따르는 타입은 '해당 프로토콜을 준수한다' 고 표현합니다. 타입에서 프로토콜의 요구사항을 충족시키려면 프로토콜이 제시하는 청사진의 기능을 모두 구현해야 합니다. 즉, 프로토콜은 정의를 하고 제시를 할 뿐이지 스스로 기능을 구현하지는 않습니다. 프로토콜은 다음과 같이 protocol 키워드를 사용하여 정의합니다. prot..
[Swift] 빠른 종료(Early Exit)
💡빠른 종료 (Early Exit) guard 키워드를 사용하여 특정 조건에 부합하지 않는다면 재빠르게 코드 블록의 실행을 종료할 수 있습니다. guard 구문은 Bool 타입의 값으로 동작하는 기능이며, 항상 else 구문이 뒤에 따라와야 합니다. 또한, guard의 else 블록 내부에는 특정 코드 블록을 종료하는 return, break, continue, throw 등의 제어문 전환 명령이 꼭 있어야 합니다. 다음은 guard 구문 표현 방식입니다. guard Bool 타입 값 else { 예외사항 실행문 제어문 전환 명령어 } if 구문을 사용하면 else 블록으로 예외사항을 처리해야 하지만 예외사항만 처리하고 싶다면 guard 구문을 사용하는 것이 훨씬 간편하고 읽기 좋게 구성할 수 있습니다...
[Swift] 옵셔널 체이닝(Optional Chaining)
💡옵셔널 체이닝 (Optional Chaining) 옵셔널에 값이 있다면 프로퍼티, 메서드, 서브스크립트 등을 호출할 수 있고, 옵셔널이 nil이라면 nil을 반환합니다. 이러한 옵셔널을 반복 사용하여 체인처럼 서로 꼬리를 물고 있는 모양을 옵셔널 체이닝이라고 합니다. 중첩된 옵셔널 중 하나라도 값이 존재하지 않는다면 결과적으로 nil을 반환합니다. 옵셔널 체이닝은 호출하고 싶은 옵셔널 변수나 상수 뒤에 물음표(?)를 붙여 표현합니다. 다음은 사람의 주소 정보 표현을 설계한 것입니다. 이를 사용하여 옵셔널 체이닝에 대한 예시를 들어보겠습니다~! // 호실 정보를 나타내는 클래스 class Room { var number: Int // 호실 번호 init(number: Int) { self.number =..
[Swift] 클로저(Closure)
💡클로저 (Closure) 일정 기능을 하는 코드를 하나의 블록으로 모아놓은 것입니다. 일급 시민(first-citizen)으로, 전달인자, 변수, 상수 등으로 저장, 전달이 가능합니다. 참조 타입입니다. 함수는 클로저의 일종으로, 이름이 있는 클로저입니다. 📌일급 객체(first-citizen)란? 전달인자로 전달할 수 있으며, 변수나 데이터 구조 안에 담을 수 있고 반환값으로 사용할 수 있는 객체을 말합니다. 🔥클로저 표현방법 { (매개변수들) -> 반환 타입 in 실행 코드 } 🔥클로저의 사용 // sum이라는 상수에 클로저 할당 let sum: (Int, Int) -> Int = { (a: Int, b: Int) in return a + b } let sumResult: Int = sum(1, 2..
[Swift] 이니셜라이저(Initialization)
💡이니셜라이저 (Initialization) 이니셜라이저를 정의하면 초기화 과정을 직접 구현할 수 있습니다. 그렇게 구현된 이니셜라이저는 새로운 인스턴스를 생성할 수 있는 특별한 메서드가 됩니다. 스위프트의 이니셜라이저는 반환 값이 없습니다. 이니셜라이저는 init 키워드를 사용하여 이니셜라이저 메서드임을 표현합니다. 기본적인 형태의 이니셜라이저는 다음과 같습니다. class SomeClass { init() { // 초기화할 때 필요한 코드 } } struct SomeStruct { init() { // 초기화할 때 필요한 코드 } } enum SomeEnum { case someCase init() { // 열거형은 초기화할 때 반드시 case중 하나가 되어야 합니다. self = .someCase ..
[Swift] 메서드(Method) - 타입 메서드
💡타입 메서드 타입 메서드는 타입 자체에 호출이 가능한 메서드를 말합니다. 메서드 앞에 다음과 같은 키워드를 사용하여 타입 메서드임을 나타내줍니다. 구조체 - static 클래스 - static(상속 후 메서드 재정의 불가능), class(상속 후 메서드 재정의 가능) class AClass { static func staticTypeMethod() { print("AClass staticTypeMethod") } class func classTypeMethod() { print("AClass classTypeMethod") } } class BClass: AClass { /* // 오류 발생! 재정의 불가! override static func staticTypeMethod() { } */ overri..
[Swift] 메서드(Method) - 인스턴스 메서드
💡 메서드(Method) 메서드는 특정 타입에 관련된 함수를 뜻합니다. 클래스, 구조체, 열거형 등 👉 실행하는 기능을 캡슐화한 인스턴스 메서드 정의 가능 👉 타입 자체와 관련된 기능을 실행하는 타입 메서드 정의 가능 💡인스턴스 메서드 인스턴스 메서드는 특정 타입의 인스턴스에 속한 함수를 뜻합니다. 특정 타입 내부에 구현할 수 있으며 인스턴스가 존재할 때만 사용할 수 있습니다. class LevelClass { // 현재 레벨을 저장하는 저장 프로퍼티 var level: Int = 0{ // 프로퍼티 값이 변경되면 호출하는 프로퍼티 감시자 didSet { print("Level \(level)") } } // 레벨이 올랐을 때 호출할 메서드 func levelUp() { print("Level Up!")..
[Swift] 프로퍼티(Property) - 타입 프로퍼티
💡 타입 프로퍼티 (Type Properties) 타입 프로퍼티는 각각의 인스턴스가 아닌 타입 자체에 속하는 프로퍼티를 말합니다. 즉, 타입 자체에 영향을 미치는 프로퍼티입니다. 인스턴스의 생성 여부와 상관없이 타입 프로퍼티의 값을 하나며, 그 타입의 모든 인스턴스가 공통으로 사용하는 값, 모든 인스턴스에서 공용으로 접근하고 값을 변경할 수 있는 변수 등을 정의할 때 유용합니다. 저장 타입 프로퍼티 변수 또는 상수로 선언할 수 있습니다. 반드시 초깃값을 설정해야 하며 지연 연산이 됩니다. (lazy 키워드 표시❌) 연산 타입 프로퍼티 변수로만 선언할 수 있습니다. class AClass { // 저장 타입 프로퍼티(상수) static let typeProperty_1: Int = 10 // 저장 타입 프..
[Swift] 프로퍼티(Property) - 프로퍼티 감시자
💡프로퍼티 감시자 (Property Observers) 프로퍼티 감시자를 사용하면 프로퍼티의 값이 변경될 때 원하는 동작을 수행할 수 있습니다. 프로퍼티의 값이 새로 할당될 때마다 호출하며 변경되는 값이 현재의 값과 같더라도 호출합니다. 프로퍼티 감시자를 적용할 수 있는 프로퍼티는 다음과 같습니다. 저장 프로퍼티 프로퍼티를 재정의해 상속받은 저장 프로퍼티 또는 연산 프로퍼티 단, 상속받지 않은 연산 프로퍼티에는 프로퍼티 감시자를 사용할 필요가 없으며 할 수도 없습니다. 그 이유는 접근자와 설정자를 통해 프로퍼티 감시자를 구현할 수 있기 때문입니다. 프로퍼티 감시자에는 willSet, didSet 두 개의 메서드가 있는데요. 각각 설명해보도록 하겠습니다! willSet 메서드 프로퍼티의 값이 변경되기 직전..