콘텐츠로 건너뛰기
Home » Development » Swift » Page 2

Swift

Swift / Cocoa / Foundation / Programming Language / UIKit / AppKit / Swift Standard Library / Swift 문법과 기능 / 공부하면서 알게된 내용들을 정리 / 어느 프로그래밍 언어 덕후의 연습장

Swift – BlockOperation 사용하기

Operation(NSOperation)은 특정한 작업을 수행하기 위한 코드와 데이터를 감싸는 객체로 해당 작업을 동기/비동기로 필요한 시점에 실행하기 위한 용도로 사용한다. NSOperation은 OSX 10.5에서도입되었는데, 이 시점의 Objective-C에서는 클래스의 외부에서 코드를 주입할 수 있는 언어적인 장치가 존재하지 않았기 때문에, 이를 사용하려면 무조건 NSOperation의 서브클래스를 만들어야 하는 불편한 점이 있었다. 따라서 간단한 코드 조각을 실행하기 위해서 NSOperation을 사용하는 것은 꽤나 불편한 일이었다.

OSX 10.6(스노우레퍼드)부터 GCC/Clang을 기본 컴파일러로 사용하게 되었고 이때부터 코드블럭 기능이 지원되었다. 즉 별도의 서브클래스를 작성하지 않더라도 코드 블럭의 형태로, 마치 클로저처럼 코드와 코드가 캡쳐링하는 데이터를 주입하여 오퍼레이션 인스턴스를 만드는 것이 가능해졌다. 실질적으로 NSOperation을 그대로 사용해야할 이유는 현재로서는 찾아보기 힘들다.

더 보기 »Swift – BlockOperation 사용하기

복사/붙여넣기를 지원하는 Swift 타입 작성하기 2

복사/붙여넣기를 지원하는 타입을 작성할 때, 해당 타입은 반드시 직렬화 및 역직렬화가 가능해야 했다. 그런데 NSPasteboardReading 프로토콜은 지정 이니셜라이저를 포함하고 있기 때문에 클래스를 직접 수정하거나 서브클래싱하지 않으면 이 방법을 적용할 수가 없다. 따라서 NSPasteboardItem을 대신 사용하는 방법을 적용해야 한다. 이 때 핵심은 해당 클래스가 어떤 모종의 방법을 사용해서 직렬화 및 역직렬화가 가능해야 한다는 점이다.

더 보기 »복사/붙여넣기를 지원하는 Swift 타입 작성하기 2

(Swift) 프로토콜 그 자체가 자신을 따르지 않는다

Swift 5.1에 추가된 some 키워드 (불투명 리턴 타입)에 관한 Swift 공식 문서를 살펴보다가 이상한 구절을 발견했다.

Another problem with this approach is that the shape transformations don’t nest. The result of flipping a triangle is a value of type Shape, and the protoFlip(_:) function takes an argument of some type that conforms to the Shape protocol. However, a value of a protocol type doesn’t conform to that protocol; the value returned by protoFlip(_:) doesn’t conform to Shape. This means code like protoFlip(protoFlip(smallTriange)) that applies multiple transformations is invalid because the flipped shape isn’t a valid argument to protoFlip(_:).

프로토콜 타입의 값이 그 프로토콜을 따르지 않는다는 것이다. 왱? 이게 뭔말이지? 특정한 프로토콜을 따르는 객체들은 그 실제 타입에 상관없이 해당 프로토콜을 타입처럼 사용할 수 있다고 했는데, 이번에는 프로토콜 타입의 값이 그 프로토콜을 따르지 않는다라니?

더 보기 »(Swift) 프로토콜 그 자체가 자신을 따르지 않는다

(Swift) Float 타입 사용법

Float 타입은 32비트 부동 소수점 숫자를 다루기 위해 제공되는 기본 타입이다. 64비트 정밀도를 가지는 Double 타입도 제공된다.


지수(exponent)와 가수(significand)에 대해

컴퓨터에서 사용하는 부동소수점 숫자는 기본적으로 근사값이다. 모두들 알다시피 컴퓨터는 내부적으로 모든 데이터를 이진수로 표현한다. 정수나 자연수에 있어서 진법은 특정한 값을 표시하는데 있어서 필요한 숫자의 개수만 달라지지만 소수점 이하의 값에 대해서는 그 사정이 다르다. 먼저 10진수 13을 생각해보자. 13은 10 + 3 이며 이를 10을 밑으로 하는 다항식으로 쓰면 1 \times 10^1 + 3 \times 10^0 의 꼴로 표현된다. 같은 식으로 이 값을 이진수로 표현하면 1011(2)가 되는데, 이 표현은 다시 이는 1\times2^3 + 0\times2^2 + 1\times2^1 + 1\times2^0 이라는 의미이다.

더 보기 »(Swift) Float 타입 사용법

FileHandle 사용법

NSData 클래스에는 해당 객체의 데이터를 URL에 기록하는 write(to:atomically:) 라는 메소드가 존재한다. 이 때 atomic하게 쓴다는 말은 온전한 데이터를 기록하거나 혹은 아예 기록하지 않거나 둘 중 하나의 결과만 존재하며, 그 중간인 부분적으로 소실되어 잘못된 데이터가 존재하지 않는다는 것을 말한다.

NSDataNSMutableData의 값 시멘틱 타입인 Data에는 해당 메소드가 존재하지 않는다. 대신 write(to:options:) 메소드가 존재하며, NSData.WritingOptions 타입에 .atomic 값이 정의되어 있어서 동일한 동작을 구현하는데에는 문제가 없다.

파일을 atomic하게 기록하는 방법은 임시 파일을 사용하는 것이다. 하나 혹은 그 이상의 임시 파일을 생성하여 데이터를 기록한 후에, 이상 없이 모든 데이터를 기록하게되면 해당 임시 파일을 최종 목적 파일로 교체하거나 복사하는 방식으로 파일 데이터가 중간에 깨지지 않게 하는 것이다.

더 보기 »FileHandle 사용법

Codable

많은 프로그래밍 작업은 데이터를 어딘가로 전달하는 것과 관련된다. 네트워크를 통해서 전송하거나, 디스크와 같은 영구 저장소로 전달하여 기록할 수도 있다. 프로그램이 실행시간에 사용하는 데이터는 그 필요와 목적에 맞게 구조화되고 각 단위가 연결되어 입체적인 그래프를 형성하기도 하지만, 전달과정에서 만큼은 일렬로 늘어선 비트의 연속체가 되어야 한다. 따라서 필연적으로 어떤 데이터가 유용성을 가지려면 직렬화 될 수 있어야 하고 그 반대로 역직렬화도 가능해야 한다.

이러한 직렬화 / 역직렬화와 관련하여 Foundation은 오래전부터 NSCoding 이라는 기술을 보유하고 있었다. 이는 간단하게 가장 기본이 되는 몇 가지 타입이 인코딩이 가능하다면, 각 객체의 속성을 키-값 쌍으로 묶어서 인코딩할 수 있다는 가정하에 일반적으로 사용될 수 있는 임의의 타입의 데이터까지 간단하게 확장할 수 있는 기술이다. (물론, 현재도 쓰인다. 단 보안상의 문제로 NSSecureCoding으로 대체되었다.)

더 보기 »Codable

NSPersistentStoreDescription

NSPersistentStoreDescription은 코어데이터의 영구저장소에 관한 여러 설정 정보들을 담고 있는 클래스이다. 이는 코어데이터 스택을 초기화하는 시점에 NSPersistentContainer나 NSPersistentStoreCoordinator에 의해서 사용된다. NSPersistentContainer를 사용하는 경우에는 디폴트 디스크립션이 자동으로 생성되기 때문에 만들 필요가 없긴한데, 저장소의 위치나 동작 방식을 커스터마징하기 위해 추가로 설정할 수 있다.

더 보기 »NSPersistentStoreDescription

Swift의 커스텀 타입을 직렬화하기

이 글은 https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types 의 내용을 일부 발췌, 의역한 것입니다.

프로그래밍 분야에서의 많은 작업은 데이터를 디스크에 저장하거나, 네트워크를 통해 전송하거나 API를 호출하기 위해 데이터를 제출하는 등의 일과 관련된다. 이 과정에서 데이터는 전송되는 동안에 적절한 형식으로 인코딩되고 다시 디코딩될 필요가 있다.

더 보기 »Swift의 커스텀 타입을 직렬화하기

Vision을 이용한 얼굴 인식 – 고급편

Vision을 이용해서 이미지 속에서 얼굴을 인식하는 방법을 살펴본 바 있는데, 당시 글에서 VNDetectFaceLandmarksRequest 를 사용했었다. 사실 얼굴이 들어있는 영역만 찾기 위해서는 VNDetectFaceRectsRequest 를 사용하는 것으로도 충분한데, face landmarks를 찾는다는 것은 얼굴의 주요 요소들 – 눈, 코, 입, 윤곽선 등-을 찾아낸다는 의미이다. 

이 글에서는 VNDetectFaceLandmarksRequest를 사용해서 실제로 얼굴의 각 요소를 추적하는 예제를 소개해 보겠다. 

더 보기 »Vision을 이용한 얼굴 인식 – 고급편