2016-11-19 1 views
0

Obj-C의 @property (nonatomic) NSArray <SomeProtocol>* items;을 미러링하는 최선의 방법은 항목이 UIView 하위 클래스 인 경우입니다. 아래의 예에서 프로토콜을 준수하는 UIView 하위 클래스의 신속한 배열

, 그러나 나는이 오류를 제공, 모든 프로토콜에 맞는지 UIKit 구성 요소 (예 : UILabel, UIButton 등)의 배열을 저장하고 싶은 몇 가지 다른 방법은 무엇 Protocol can only be used as a generic constraint because it has Self or associated type requirements

이 모델링?

예 놀이터 :

import UIKit 

/// Protocol representing a form field model 
protocol FieldRepresentable {} 

/// Protocol representing a form UI control 
protocol FormControllable { 
    associatedtype FieldRepresentable 

    init(model: FieldRepresentable) 

    var model: FieldRepresentable { get } 
} 

/// Example label model 
class FormLabelElement: FieldRepresentable {} 

/// Example label UI control 
class FormLabel: UILabel, FormControllable { 

    required init(model: FormLabelElement) { 
     self.model = model 

     super.init(frame: CGRect.zero) 
    } 

    let model: FormLabelElement 

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 
} 

/// Example form 
class Form: UIView { 

    // Error here 
    var fields: [FormControllable]? 

} 
+0

아마도이 기사는 도움이 될 수 있습니다. https://milen.me/writings/swift-generic-protocols/ – nebs

+0

프로토콜을 클래스에만 적용한다는 것을 나타 내기 위해 프로토콜을': class'로 선언해야합니다 구조체가 아닌 객체 – Paulw11

답변

0

네이트 쿡은 그 FormControllable에서 관련 유형을 제거하고 init failable을하는 것입니다 접근하는

하나의 간단한 틱 방법을

을 제안했다. 일치하는 각 유형은 기본적으로 전달 된 특정 FieldRepresentable 유형으로 수행 할 작업을 알고 있는지 확인해야합니다. 그래서 그 접근 방식에 대한 최종 버전은 결국 당신이 유형의 안전/표현의 조금 잃을 것입니다하지만 비 균일 배열

을 할 수있는 능력을 얻을 것이라고 생각 존재 :

import UIKit 

/// Protocol representing a form field model that is used to instantiate a UI control 
protocol FieldRepresentable: class {} 

/// Protocol representing a form UI control 
protocol FormControllable: class { 
    init?(model: FieldRepresentable) 
} 

/// Example label model 
class FormLabelElement: FieldRepresentable {} 

/// Example label UI control 
class FormLabel: UILabel, FormControllable { 

    required init?(model: FieldRepresentable) { 
     guard let model = model as? FormLabelElement else { return nil } 
     self.model = model 

     super.init(frame: CGRect.zero) 
    } 

    let model: FormLabelElement 

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 
} 

/// Example form 
class Form: UIView { 
    var fields = [FormControllable]() 
} 

// Create a form 
let form = Form() 
let labelModel = FormLabelElement() 
let labelField = FormLabel(model: labelModel)! 
form.fields.append(labelField) 
print(form.fields) 

form.fields.forEach { (field) in 
    if field is FormLabel { 
     print("We have a label field") 
    } 
} 

모델 프로토콜이 충분히 일반적인 경우

또한, Soroush는

하나의 아이디어는 프로그래머 일련 번호 때문에, 열거로 필드 표현할 수있는 유형을 확인하는 것입니다 제안 양식 필드 요소 유형의

그런 다음 당신은 당신이 필드 데이터의 경우 배열을 가지고 폼 요소의 배열에 매핑 할 수 있습니다

그리고 폼 요소로 열거를 켤 수있는 큰 스위치를 필요

관련 문제