【问题标题】:Swift computed property templates?Swift 计算属性模板?
【发布时间】:2016-09-04 13:17:59
【问题描述】:

有没有办法对计算属性进行模板化以避免一遍又一遍地重复相同的代码?例如,现在我有一个类,其代码块如下所示:

private var _state:State?
private var _maxs:State?
private var _state1s:State?
private var _state10s:State?

var state:State? {
    get {
        dispatch_semaphore_wait(statephore, DISPATCH_TIME_FOREVER)
        let s=_state
        dispatch_semaphore_signal(statephore)
        return s
    }
    set {
        dispatch_semaphore_wait(statephore, DISPATCH_TIME_FOREVER)
        _state=newValue
        dispatch_semaphore_signal(statephore)
        if newValue != nil {statsTest(newValue!)}
    }
}

var maxs:State? {
    get {
        dispatch_semaphore_wait(maxphore, DISPATCH_TIME_FOREVER)
        let m=_maxs
        dispatch_semaphore_signal(maxphore)
        return m
    }
    set {
        dispatch_semaphore_wait(maxphore, DISPATCH_TIME_FOREVER)
        _maxs=newValue
        dispatch_semaphore_signal(maxphore)
    }
}


var state1s:State? {
    get {
        dispatch_semaphore_wait(state1sphore, DISPATCH_TIME_FOREVER)
        let s=_state1s
        dispatch_semaphore_signal(state1sphore)
        return s
    }
    set {
        dispatch_semaphore_wait(state1sphore, DISPATCH_TIME_FOREVER)
        _state1s=newValue
        dispatch_semaphore_signal(state1sphore)
    }
}

var state10s:State? {
    get {
        dispatch_semaphore_wait(state10sphore, DISPATCH_TIME_FOREVER)
        let s=_state10s
        dispatch_semaphore_signal(state10sphore)
        return s
    }
    set {
        dispatch_semaphore_wait(state10sphore, DISPATCH_TIME_FOREVER)
        _state10s=newValue
        dispatch_semaphore_signal(state10sphore)
    }
}

这里有一个明显的模式,所有重复的代码只会混淆正在发生的事情,并在我剪切/粘贴/编辑/失败时导致错误。有没有一种方法可以捕获这种模式,然后使用以下内容定义我的属性:

var state=ProtectedValue(_state,statephore)

?

【问题讨论】:

  • 您不需要在 getter 中使用信号量,因为无需防止资源争用。
  • 行为可能会出现在 Swift 3 中(参见 github.com/apple/swift-evolution/blob/master/proposals/…
  • @AMomchilov,在这种情况下,此状态在异步队列之间共享,因此需要保护接口。仍在学习这是否是处理它的最佳方法,但我的问题的重点是,多个属性共享几乎相同的访问模式的想法看起来会经常出现。
  • @Kevin,行为看起来就像我的目标。基本上是一个带有 get/set 的类或类似的东西,在属性访问时会被调用。

标签: swift computed-properties


【解决方案1】:

这看起来像是泛型和inout 变量的工作。

func setProtectedValue<T>(inout destination: T, newValue: T, semaphore: SemaphoreType) {
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
        destination = newValue
        dispatch_semaphore_signal(semaphore)
}

在通话地点:

var state10s:State? {
    get {
        //...
    }
    set {
        setProtectedValue(&_state10s, newValue, state10sphore)
    }
}

【讨论】:

  • 哎呀,我不小心把_state10s = 放到了不属于它的地方。请参阅我的更新答案。每个 setter 调用应该只触发 1 次等待
  • 谢谢,仍然没有我想要的那么干净,但可能会尽可能接近,直到出现行为或类似情况。
  • 我会创建一个通用结构来封装信号量及其保护的数据
  • 是的,我认为这是目前最好的方法。当我说“不像我想要的那样干净”时,我的意思是 Swift 在这方面不像我想要的那样干净——这不是对你的回应的批评。理想情况下,我不想用gets和sets混淆声明,而是以某种方式封装它们。行为看起来是朝着这个方向迈出的一步,但在那之前你所提议的看起来像是最少的冗余代码。
  • 除了行为之外,我不确定如何缓解这种情况。
猜你喜欢
  • 1970-01-01
  • 2016-02-10
  • 2019-02-14
  • 2012-12-08
  • 2016-04-22
  • 2016-08-02
  • 2018-02-03
  • 2018-11-12
  • 2020-08-02
相关资源
最近更新 更多