The Swift Programming Language. Automatic Reference Counting (1)

Automatic Reference Counting 스위프트는 자동 참조 카운팅(ARC)을 사용하여 앱의 메모리 사용량을 추적하고 관리한다. 대부분의 경우에, 스위프트에서 메모리 관리는 “그냥 작동"하고, 메모리 관리를 직접 할 생각을 하지 않아도 된다. ARC는 클래스 인스턴스가 더 이상 필요하지 않게 되었을 때, 자동적으로 해당 메모리를 비우게 된다. 하지만, 경우에 따라 ARC는 메모리 관리를 위해 코드 내부에서의 관계**(주: 원문은 relationships between parts of your code, 코드 부분들 간의 관계)** 에 대한 정보를 요구할 때가 있다. 이 챕터는 이러한 상황들을 설명하고, 어떻게 ARC가 앱의 메모리를 관리하는지를 보여준다. ...

August 15, 2023

The Swift Programming Language. Opaque Types (2)

Boxed Protocol Types 박스드 프로토콜 타입은 “there exists a type T such that T conforms to the protocol” 라는 구절에서 따와 실존적 타입 (existential type) 이라고도 한다. 박스드 프로토콜 타입을 만들기 위해, 프로토콜 이름 앞에 any를 작성한다. 다음은 예시이다: struct VerticalShapes: Shape { var shapes: [any Shape] func draw() -> String { return shapes.map { $0.draw() }.joined(separator: "\n\n") } } let largeTriangle = Triangle(size: 5) let largeSquare = Square(size: 5) let vertical = VerticalShapes(shapes: [largeTriangle, largeSquare]) print(vertical.draw()) 위의 예시에서, VerticalShapes는 도형들의 타입을 박스드 Shape 원소들의 배열인 [any Shape]로 선언한다. 배열의 각 원소들은 서로 다른 타입일 수 있지만, 반드시 Shape 프로토콜을 준수해야 한다. 런타임에 유연성을 지원하기 위해, 스위프트는 필요할 때 박스(box)라는 간접적인 단계를 추가한다. 박스는 성능 코스트가 있다. ...

August 13, 2023

The Swift Programming Language. Opaque Types (1)

Opaque and Boxed Types 스위프트는 값의 타입에 대한 상세한 정보를 숨기는 두가지 방법을 제공한다: 불투명한 타입과 박스형 프로토콜 타입이다. 타입의 정보를 숨기는 것은 모듈과 모듈을 호출하는 코드의 경계에서 유용하다, 리턴 값의 타입이 공개되지 않은 채로 유지될 수 있기 때문이다. 함수나 메소드는 리턴 값의 타입 정보를 숨기기 위해 불투명한 타입을 리턴하다. 함수의 리턴 타입을 구체적으로 제공하는 대신에, 리턴 값은 값이 지원하는 프로토콜로 묘사된다. 불투명한 타입은 타입의 정체를 보존한다 — 컴파일러는 타입 정보에 대해 접근이 가능하지만, 모듈의 클라이언트들은 불가능하다. ...

August 12, 2023

The Swift Programming Language. Generics (5)

Generic Where Clauses 타입 제약조건을 사용하면 제너럴 함수, 서브스크립트, 타입에 관련된 타입 파라미터의 요구사항을 정의할 수 있다. 이는 연관 타입의 제약 조건을 정의하는데에도 유용하며, 제네릭 where 절을 정의하여 할 수 있다. 제네릭 where절은 연관 타입이 반드시 특정 프로토콜을 준수하게 하거나, 특정한 타입 파라미터와 연관 타입이 반드시 같아야 함을 요구할 수 있다. 제네릭 where절은 where 키워드로 시작하고, 뒤에 연관 타입의 제약조건이나 타입 파라미터와 연관 타입의 동등 관계를 작성한다. 제네릭 where절은 타입이나 함수의 본문의 여는 중괄호 바로 앞에 작성한다. ...

August 8, 2023

The Swift Programming Language. Generics (4)

Associated Types 프로토콜을 정의할때, 프로토콜의 정의의 일부로 하나 혹은 그 이상의 연관 타입(associated type) 을 선언하는 것이 유용할 때가 있다. 연관 타입은 프로토콜의 일부로 사용되는 타입에게 플레이스홀더 이름을 부여한다. 해당 연관 타입이 될 실제 타입은 프로토콜이 적용될 때 까지 지정되지 않는다. 연관 타입은 associatedtype 키워드로 특정할 수 있다. Associated types in Action 다음은 연관 타입으로 Item을 선언하는 프로토콜 Container의 예시이다: protocol Container { associatedtype Item mutating func append(_ item: Item) var count: Int { get } subscript(i: Int) -> Item { get } } Container 프로토콜은 모든 컨테이너가 반드시 제공해야할 세 개의 필수 요구사항을 정의한다. ...

August 7, 2023

The Swift Programming Language. Generics (3)

Type Constraints swapTwoValues(_:_:) 함수와 Stack 타입은 어떠한 타입으로도 작업할 수 있다. 하지만 특정한 타입 제약조건(type constraints) 을 강제하여 제네릭 함수나 제네릭 타입이 사용할 수 있는 타입을 지정하는 것이 유용할 때가 있다. 타입 제약조건은 타입 파라미터가 특정한 클래스를 상속 받거나, 특정 프로토콜을 준수해야 하도록 지정한다. 예를 들어, 스위프트의 Dictionary 타입은 딕셔너리의 키로 사용할 수 있는 타입에 제한을 둔다. 딕셔너리의 키로 사용될 타입은 반드시 hashable 해야한다. 즉, 스스로를 유니크하게 구분할 수 있어야 한다. ...

August 4, 2023

The Swift Programming Language. Generics (2)

Generic Types 제네릭 함수와 다르게, 스위프트는 제네릭 타입도 정의할 수 있게 해준다. 이는 Array나 Dictionary처럼 모든 타입과 함께 작업할 수 있는 커스텀 클래스, 스트럭처, 열거형이다. 이 섹션은 스택이라는 제네릭 컬렉션 타입을 작성하는 방법을 보여준다. 스택은 배열과 비슷하게 순서가 있는 값들의 집합이다, 하지만 스위프트의 Array 타입보다 더 제한된 작업을 한다. 배열은 배열의 어느 위치에서나 값을 삽입하거나 제거할 수 있지만, 스택은 컬렉션의 끝 부분에서만 삽입(pushing)이나 삭제(popping)을 할 수 있다. ...

August 2, 2023

The Swift Programming Language. Generics (1)

Generics 제네릭 코드(Generic code) 는 정의한 요구사항을 만족하는 모든 타입과 함께 작업할 수 있는 유연하고 재사용성 높은 함수나 타입을 작성하게 해준다. 코드의 중복을 피하고, 의도를 추상적이고 명확한 방법으로 표현할 수 있다. 제네릭은 스위프트의 강력한 특징 중 하나이며, 많은 스위프트의 표준 라이브러리는 제네릭 코드로 빌드 되어있다. 사실 인지하지 못했어도 Language Guide 내내 제네릭 코드를 사용했다. 예를 들어, 스위프트의 Array와 Dictionary 타입은 둘 다 제네릭 컬렉션이다. Int 값을 저장하는 배열, String 값을 저장하는 배열, 혹은 스위프트에서 만들 수 있는 어떠한 다른 타입이라도 저장하는 배열 등을 생성할 수 있다. 비슷하게, 어떤 타입이든지 간에 특정한 타입을 저장하는 딕셔너리를 만들 수 있다. ...

August 1, 2023

The Swift Programming Language. Protocols (5)

Protocol Extensions 프로토콜은 메소드, 이니셜라이저, 서브스크립트, 컴퓨티드 프로퍼티를 해당 프로퍼티를 준수하는 타입들에게 제공하도록 확장될 수 있다. 이는 각 타입의 개별 준수나 전역 함수가 아니라 프로토콜 스스로 동작을 정의할 수 있게 해준다. 예를 들어, RandomNumberGenerator 프로토콜은 random() 메소드 요구사항의 결과값을 사용하여 랜덤 Bool 값을 리턴하는 randomBool() 메소드를 제공하도록 확장될 수 있다. extension RandomNumberGenerator { func randomBool() -> Bool { return random() > 0.5 } } 프로토콜의 익스텐션을 만들면, 해당 프로토콜을 준수하는 모든 타입은 추가적인 수정 없이 모든 이러한 메소드 구현을 자동적으로 얻게 된다. ...

July 4, 2023

The Swift Programming Language. Protocols (4)

Protocol Composition 하나의 타입이 여러개의 프로토콜을 동시에 준수하도록 하는 것이 유용할 때가 있다. 프로토콜 구성(protocol composition) 을 통해 여러 개의 프로토콜을 하나의 프로토콜로 결합할 수 있다. 프로토콜 구성은 내부에 있는 모든 프로토콜의 요구사항을 결합한 임시 로컬 프로토콜을 정의한 것처럼 동작한다. 하지만 프로토콜 구성은 어떠한 새로운 프로토콜 타입도 정의하지 않는다. 프로토콜 구성은 SomeProtocol & AnotherProtocol의 형태를 가진다. 앰퍼샌드로 구분하여 필요한 수 만큼 프로토콜을 나열할 수 있다. 프로토콜 리스트에 추가로 프로토콜 구성은 필요로 하는 슈퍼클래스로 지정하기 위해 하나의 클래스 타입을 포함할 수도 있다.(주: 프로토콜 구성을 준수하려면 특정 클래스의 서브클래스이어야 할 때, 슈퍼클래스도 그 프로토콜 구성 내부에 포함시킨다.) ...

July 3, 2023