【问题标题】:initialization phases - can this be done more easily?初始化阶段 - 这可以更容易地完成吗?
【发布时间】:2017-11-27 16:16:56
【问题描述】:

我有一个实现 MultipeerConnectivity 的类,我想要一个子类来为广告商实现它。这是我想要的:

class ConnectionManager: NSObject {

  let serviceType: String
  let peerID: MCPeerID
  let session: MCSession
  var delegate: ViewController!

  override init() {
    serviceType = "mc-service"
    peerID = MCPeerID(displayName: UIDevice.current.name)
    session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
    super.init()
    session.delegate = self
  }
}

class AdvertiserConnectionManager: ConnectionManager {

  let assistant: MCAdvertiserAssistant

  override init() {
    assistant = MCAdvertiserAssistant(serviceType: serviceType, discoveryInfo: nil, session: session)
    super.init()
    assistant.delegate = self
    assistant.start()
  }
}

但这违反了 init() 的分阶段规则,因为 MCAdvertiserAssistant(serviceType:, discoveryInfo:, session:) 使用 serviceTypesession , 超类的两个属性。

我已经对子类做了以下操作,通过懒惰地声明 assistant 来作弊。这行得通!为什么?初始化器仍然需要调用self!!!我不得不做这种不自然的事情来创建我的子类。而且我可能已经颠覆了要避免的分阶段!

class AdvertiserConnectionManager: ConnectionManager {

  lazy var assistant: MCAdvertiserAssistant = {
    MCAdvertiserAssistant(serviceType: serviceType, discoveryInfo: nil, session: session)
  }()

  override init() {
    super.init()
    assistant.delegate = self
    assistant.start()
  }
}  

【问题讨论】:

    标签: swift lazy-initialization


    【解决方案1】:

    你没有作弊,这不是一件不自然的事情。这是初始化相互依赖的对象属性的常用方法。

    来自documentation (Swift Language Guide: Properties)

    惰性存储属性是一个属性,其初始值直到第一次使用时才计算出来。
    ...
    当属性的初始值依赖于外部因素时,惰性属性很有用,这些因素的值在实例初始化完成之前是未知的。

    在您的情况下,assistant 将在selfserviceTimesession 有效且可用时在super.init 调用之后被初始化。

    【讨论】:

      猜你喜欢
      • 2015-03-26
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 2020-12-07
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      相关资源
      最近更新 更多