2017-12-06 2 views
0

의 나는 다음과 같은 인프라 있다고 가정 해 봅시다 :프로토콜

protocol Naming { 
    var printer: Printer { get } 
    var name: String { get } 
} 

extension Naming { 
    var name: String { return "\(type(of: self))" } 

    func printName() { 
     printer.print(name) 
    } 
} 

protocol Printer { 
    func print(_: String) 
} 

는 그들이 MCVE를 구축하는 묶는의 결과, 이름에 나와 함께 맨발하세요 :). 기본적으로 이름을 인쇄하는 데 사용되는 이름과 프린터를 표시하는 프로토콜이 있습니다.

지금, MVC를 따라하려고, 나는이 추가

그들이 모델을 허용하고, 이러한 경우 허용에 그들을 단순히 프로토콜 적합성을 전달하여 Naming에 맞도록 지정하는 뷰 컨트롤러를 허용
protocol ModelInjectable { 
    associatedtype Model 
    var model: Model { get } 
} 

extension Naming where Self: ModelInjectable, Self.Model: Naming { 
    var printer: Printer { return model.printer } 
    var name: String { return model.name } 
} 

모델.

이 간단한 VC입니다 :

struct MyModel: Naming { 
    let printer: Printer 
} 

작품이 예상대로, 그러나

protocol MyModel: Naming { 
} 

:

class MyViewController: UIViewController, ModelInjectable, Naming { 
    let model: MyModel 

    required init(model: MyModel) { 
     self.model = model 
     super.init(nibName: nil, bundle: nil) 
    } 

    required init?(coder: NSCoder) { 
     fatalError() 
    } 
} 

I 모델에 대한 프로토콜을 사용하려고 할 때 문제가 발생 컴파일 오류가 발생합니다 :

error: type 'MyViewController' does not conform to protocol 'Naming' class MyViewController: NSViewController, ModelInjectable, Naming {

note: candidate has non-matching type 'Printer' var printer: Printer { return model.printer }

note: protocol requires property 'printer' with type 'Printer'; do you want to add a stub? var printer: Printer { get }

콘크리트 유형을 사용할 때만 컴파일러에서 extension Naming where Self: ModelInjectable, Self.Model: Naming 확장자를 사용합니다. 프로토콜 참조를 사용하면 트릭을 수행하지 않습니다. 컴파일러의 한계입니까, 아니면 잘못 사용하고 있습니까?

+0

[프로토콜이 자체에 부합하지 않습니까?] (https://stackoverflow.com/q/33112559/2976878) – Hamish

답변

1

Objective-C 프로토콜의 경우 Swift 프로토콜이 자체적으로 준수하지 않습니다. 따라서 protocol MyModel: Naming은 프로토콜 확장의 Self.Model: Naming 제약 조건을 충족하지 못합니다.

+0

흠 ... 너무 나쁩니다. 디자인에 의한 것인가? – Cristik

+0

일반적인 경우에는 해결할 수있는 문제는 아니지만 정적 요구 사항이없는 프로토콜 (예 : 정적 메서드, 초기화 프로그램 및 관련 유형 없음)에 대해 컴파일러가 허용 할 수 있습니다. 자세한 내용은 [Hamish의 우수한 답변] (https://stackoverflow.com/a/43408193/116862)을 참조하십시오. –

+0

다른 링크, 실제로 매우 상세하고 좋은 답변 주셔서 감사합니다. – Cristik