swift에 적용합니다.self와.Type

2270 단어
플러그인화 플레이어를 개발할 때 플러그인을 대량으로 초기화하는 수요를 만났다. 서로 다른 플레이어는 서로 다른 플러그인 목록을 설정해야 하고, 모든 플러그인의 구조 함수는 다르다.그래서if-else가 아닌 일반적인 방식으로 초기화를 해야 한다.다음과 같은 플러그인을 초기화해야 한다고 가정합니다.
/**      */
protocol Plugin { }
/**   A */
struct PluginA : Plugin {
    let startTimePoint: Int
}
/**   B */
struct PluginB : Plugin {
    let playRate: Float
    let showStatusbarAtFirst: Bool
}

하나의 간단한 방법은'뚱뚱한 인터페이스'를 이용하여 모든 플러그인에 가능한 모든 파라미터를 전달하여 일반적인 효과를 얻는 것이다.
/**          */
struct PluginBuildParams {
    let startTimePoint: Int
    let playRate: Float
    let showStatusbarAtFirst: Bool
}
/**           */
protocol PluginBuilder {
    static func build(with params: PluginBuildParams) -> Plugin
}
/**   -    A */
extension PluginA : PluginBuilder {
    static func build(with params: PluginBuildParams) -> Plugin {
        return self.init(startTimePoint: params.startTimePoint)
    }
}
/**   -    B */
extension PluginB : PluginBuilder {
    static func build(with params: PluginBuildParams) -> Plugin {
        return self.init(playRate: params.playRate, showStatusbarAtFirst: params.showStatusbarAtFirst)
    }
}

이 때 확장 방법을 호출하려면 ObjC의 [class build WithParams:params]와 비슷한 [class build WithParams:params]만 있으면 됩니다.swift에서 Class와 대응하는 것은 Type입니다. 컴파일링 기간에 XX를 사용할 수 있습니다.Type 실례를 가져오려면 type (of: instance) 을 사용하십시오. (Type은 기본 클래스 (프로토콜) 가 없기 때문에 [Any] 로 저장해야 합니다.)그 다음에 Type을 PluginBuilder의 Type으로 바꾸면 됩니다. 즉, type as?PluginBuilder.Type.그래서 알 수 있듯이.Type은 를 정의하는 데 사용됩니다.self 는 현재 Type의 인스턴스입니다.구체적인 코드는 다음과 같습니다.
//   params  
let params = PluginBuildParams(startTimePoint: 30, playRate: 1.25, showStatusbarAtFirst: true)
//   Type  
let pluginTypes: [Any] = [PluginA.self, PluginB.self]
for type in pluginTypes {
    //      PluginBuilder  
    if let target = type as? PluginBuilder.Type {
        //       
       print("plugin: \(target.build(with: params))")
    }
}

위에서 설명한 일반 에이전트를 사용하는 경우 코드는 다음과 같이 간략화할 수 있습니다.
//      target
let proxy = Proxy()
proxy.addTarget(target: PluginA.self)
proxy.addTarget(target: PluginB.self)
//        
proxy.invoke { (target: PluginBuilder.Type) in
    print("plugin: \(target.build(with: params))")
}

좋은 웹페이지 즐겨찾기