综合技术

为 protocol 中属性添加默认值

微信扫一扫,分享到朋友圈

为 protocol 中属性添加默认值
0

protocol
中属性可以声明为 { get }
或者 { get set }
。大多数人第一眼肯定觉得 { get }
是约束为 read-only 属性, { get set }
是约束为 read-write 属性。但是在 protocol
中这些约束都是最小约束,也就是说 { get }
属性至少需要是 readable 的,至于它是否 writable 并不作要求; { get set }
则明确的指出了属性必须是可读写,但是官方文档说明了,用 { get set }
声明的属性,不能在遵守该协议的类型中被实现为 let
属性。

The getter and setter requirements can be satisfied by a conforming type in a variety of ways. If a property declaration includes both the get
and  set
keywords, a conforming type can implement it with a stored variable property or a computed property that is both readable and writeable (that is, one that implements both a getter and a setter). However, that property declaration can’t be implemented as a constant property or a read-only computed property. If a property declaration includes only the  get
keyword, it can be implemented as any kind of property. For examples of conforming types that implement the property requirements of a protocol, see  Property Requirements
.

给属性设置默认值

给属性设置默认值?这难道不简单?

protocol FloatingViewProtocol {
    var isDraggable: Bool { get }
}

extension FloatingViewProtocol {
    var isDraggable: Bool {
        return true
    }
}

class FloatingView: FloatingViewProtocol {
    var isDraggable = false
}
复制代码

给一个 { get }
属性提供默认值,只需要在 extension
中一个 return
就搞定,确实很简单,但是这里出现了个问题,在尝试给 FloatingView
对象
isAutoAdsorb
属性重新赋值时会报错,提示 isDraggable is a get-only property

所以如果想要重新赋值,则该属性必须是 { get set }
的,可给 { get set }
属性提供默认值也比较尴尬:

protocol FloatingViewProtocol {
    var isDraggable: Bool { get set }
}

extension FloatingViewProtocol {
    var isDraggable: Bool {
        get { return true }
        set { }
    }
}

class FloatingView: FloatingViewProtocol { }
复制代码

如上确实提供了默认值,但是 set { }
实在谈不上优雅,并且还有个致命的问题, isDraggable
不是个存储属性。如果 FloatingView
在声明时采用了默认的 isDraggable
值,那么给 FloatingView
对象
isAutoAdsorb
属性重新赋值并不会被保存下来!

话说这个时候,我们是不是该联想一下属性和实例变量的关系 :)

class FloatingViewProtocolComponent {
    var isDraggable = true
    public init() {}
}

protocol FloatingViewProtocol {
    var component: FloatingViewProtocolComponent { get }
    var isDraggable: Bool { get set }
}

extension FloatingViewProtocol {
    var isDraggable: Bool {
        get { return component.isDraggable }
        set { component.isDraggable = newValue }
    }
}

class FloatingView: FloatingViewProtocol {
    var component = FloatingViewProtocolComponent()
}
复制代码

通过一个 component
属性来实现类似实例变量的功能,操作还是有点骚。

实现 component 的 protocol 中的 get set

上面提到苹果文档指明了 { get set }
声明的属性不能被实现为 let
。但是因为 component
提供了默认值,那么该 { get set }
属性就可以不被实现,同时类可以声明一个同名同类型的 let
属性覆盖协议中的属性,就造成了 { get set }
属性可以被声明为 let
的假象。

阅读原文...

微信扫一扫,分享到朋友圈

为 protocol 中属性添加默认值
0
稀土掘金

[人云亦云]http 的缓存机制

上一篇

《侏罗纪世界:进化》加入新拍照模式 拍出最靓恐龙

下一篇

评论已经被关闭。

插入图片

热门分类

往期推荐

为 protocol 中属性添加默认值

长按储存图像,分享给朋友