콘텐츠로 건너뛰기
Home » protocol

protocol

(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에서는 이 내용을 코드로 표현하면 아래와 같이 나타낼 수 있다. 이 때 몇 가지 디테일에… 더 보기 »제네릭타입을 활용한 델리게이트 패턴

required 가 붙은 이니셜라이저

UIView, UIViewController를 서브클래싱하는 코드를 작성하면서 init(frame:)을 오버라이딩하는 코드를 작성하면, Xcode는 매번 init?(coder:)가 정의되지 않았다는 컴파일 에러를 낸다. 일단 이 에러를 해결하려면 간단하게 부모 클래스의 이니셜라이저를 그대로 호출해주기만 하면 된다.

required override init?(coder aDecoder: NSCoder!) {
    super.init(coder: aDecoder)
}

왜 이 init?(coder:)는 자동으로 상속이 안되는 것일까?

잠깐, 이니셜라이저 관련한 프로그래밍 가이드에서는 required 이니셜라이저는 서브클래스에서 오버라이딩할 때 override를 붙이지 않는다고 했는데? Xcode는 override를 붙여야 한다고 한다. 이 부분은 재확인이 필요하다.
(https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID203)

더 보기 »required 가 붙은 이니셜라이저

(Swift) Array 완전정복 – 02. Sequence 프로토콜

Sequence

시퀀스(Sequence)는 직역하면 연속열이 될 수 있으며, 문자 그대로 개개의 원소들을 순서대로 하나씩 순회할 수 있는 타입을 의미한다. (Swift 기본 타입에 대해서는 사실상 모든 집합 타입이 이에 해당한다.) 시퀀스는 사실 Swift 문법과 밀접한 관련이 있는데, 바로 for - in 구문에 사용된다는 점이다.1더 보기 »(Swift) Array 완전정복 – 02. Sequence 프로토콜

What Happened to NSMethodSignature?

NSInvocation에 대해 찾아보다가 Swift 공식 블로그에서 찾은 글을 간단히 번역해본다.

https://developer.apple.com/swift/blog/?id=19

What Happened to NSMethodSignature?

코코아 프레임워크를 Swift로 옮기는 것은 우리 스스로가 우리의 API를 새로운 관점에서 볼 수 있는 좋은 기회가 되었습니다. 우리는 Swift의 목표에 맞지 않는다고 생각되는 클래스들을 찾았고, 우리의 우선순위는 주로 안전성에 맞췄습니다. 예를 들어 동적인 메소드 호출(dynamic method invocateion)과 관련된 클래스들은 Swift에 반입되지 않습니다. 이러한 클래스에는 NSInvocationNSMethodSignature가 있지요.
우리는 최근에 이 클래스들이 빠져있음을 발견한 한 개발자로부터 버그 리포팅을 받았습니다. 이 개발자는 Objctive-C에서 메소드 인자들의 타입을 검사하는데 NSMethodSignature를 사용하고 있었고, Swift로 마이그레이션하는 과정에서 이 클래스를 사용할 수 없다는 것을 알았습니다. 실제 그 코드는 인자 타입이 정해지지 않은 HTTP 핸들러릘 받도록 되어 있었습니다. 예를 들면 이런 것들이죠.더 보기 »What Happened to NSMethodSignature?

[Swift] 연관 타입(Associated Type)

연관타입(Associated Type)

Objective-C의 Associated Object와 비슷한 명칭이라 좀 헷갈릴 수 있는데, 연관타입은 프로토콜 등에서 현재 타입과 관련이 있는 타입을 의미한다.

연관타입은 프로토콜의 일부에 쓰이는 어떤 타입에 대한 플레이스홀더같은 것으로 프로토콜이 실제로 적용되기 전에는 사용되지 않는 타입1을 말한다. 연관타입은 typealias 키워드를 통해 정의한다. 다음 예는 Container라는 프로토콜의 정의이다.

protocol Container {
    typealias ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i:Int) -> ItemType { get }
}

위 프로토콜은 세 가지 특정을 정의하고 있다. 더 보기 »[Swift] 연관 타입(Associated Type)

[Objective-C] 프로토콜

클래스는 서로 다르지만 A라는 똑같은 메소드를 하나씩 가지고 있는 어떤 객체들이 있다고 하자. 방금 A라는 메소드를 가지고 있다고 가정했기 때문에 이 객체들에게는 A라는 메시지를 보냈을 때 해당 메소드가 실행될 것이라는 게 보장된다. 프로토콜은 이처럼 특정한 메소드를 구현해서 갖추고 있겠다는 약속을 말한다.

어떤 객체가 특정한 프로토콜을 따르고 있다면, 그 프로토콜에서 선언된 메소드는 구현하고 있다는 의미이며, 해당 메소드를 호출할 수 있다. 이 때 객체의 클래스가 무엇인지는 관심의 대상이 아니다.

프로토콜은 Objective-C의 기능으로 “선언만 되고 구현되지 않은” 메소드를 말한다. 이 기능은 흔히 ‘다중 상속을 지원하지 못하는 Objective-C의 기능을 보완하기 위해’ 만들어졌다고 하는데, 틀려먹은 이야기이고… Swift에서는 특히 중요하고 광범위하게 사용되기 때문에 주목을 많이 받는데, Objective-C에서는 그렇게 중요하게 다뤄지지 않았던 거 같아서 (아니, 다루는 블로그가 별로 없었지) 정리하도록 하겠다.

어떤 객체의 클래스에 대해서 알고 있다면, 이 클래스가 제공하는 인터페이스를 통해서 우리는 객체가 지원하는 기능들을 사용할 수 있게 된다. 거꾸로 어떤 특정한 기능이 필요하다면 우리는 그러한 기능을 지원하는 클래스를 선택해서 사용해야 한다. 그런데 특정한 기능은 정해져 있지만, 어떤 클래스를 사용하게 될지 알 수 없다면 어떻게 할까?

더 보기 »[Objective-C] 프로토콜