在OC时代
,第三方库为现有系统类添加方法为了防止后续和系统函数冲突,采用了添加自定义前缀的方式,比如Masonry
使用mas_
前缀
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(superview);
}];
Swift因为有着点语法的良好提示,所以现在更流行通过添加命名空间去添加拓展,比如SnapKit
的snp
box.snp.makeConstraints { (make) -> Void in
make.width.height.equalTo(50)
make.center.equalTo(self.view)
}
通过命名空间去拓展,不仅代码提示更加顺畅,而且不用频繁的去用import导入库,所以在Swift中用的更多。
实现原理
命名空间形势的拓展,本质上是用一个结构体去保存了创建的对象,比如HDSwiftCommonTools这个库的这段字符串加密
let string = "是胡不是霍"
_ = string.hd.encryptString(encryType: .md5)
string.hd
是创建了一个结构体HDNameSpace
,这个结构体实现了encryptString(encryType: .md5)
的方法
extension HDNameSpace {
func encryptString(encryType: HDEncryType, lowercase: Bool = true) -> String {
...
}
}
string.hd
除了创建结构体,还可以把string
这个变量传给结构体存起来,这样在encryptString
这个函数里,HDNameSpace
就可以通过存起来的变量去操作了。
代码实现
命名空间的结构体,HDNameSpace
可以自由命名,这里只是个示例
public struct HDNameSpace <T> {
let object: T //存储的实例对象
internal init(object: T) {
self.object = object
}
}
针对字符串最简单的实现,hd
是一个示例,自己可以随意命名
extension String {
var hd :HDNameSpace<String> {
return HDNameSpace(object: self)
}
}
public extension HDNameSpace where T == String {
func ssssss() -> Void {
print(object)
}
}
这样就实现了string.hd.ssssss()
,这样调用就会把string
打印出来了。
更高阶用法
为了更加方便统一,这里可以使用协议约束一下命名,防止出现String
调用的时候是hd
,View
调用的时候关键词变成了md
这种智障问题
//实现命名空间需遵守的协议
public protocol HDNameSpaceWrappable {
associatedtype WrapperType
var hd: WrapperType { get }
static var hd: WrapperType.Type { get }
}
//协议默认的实现方式
public extension HDNameSpaceWrappable {
var hd: HDNameSpace<Self> {
return HDNameSpace(object: self)
}
}
这样刚才的String
的拓展直接写成遵守协议就行了,有默认实现,可以不用再自己写hd实现了
extension String: HDNameSpaceWrappable {
}
public extension HDNameSpace where T == String {
func ssssss() -> Void {
print(object)
}
}
注意事项
1、public extension HDNameSpace where T == String
这句话是约束了对应类型
where 后面的 WrappedType 约束可以使用 == 或者 : ,两者是有区别的。如果扩展的是值类型
,比如 String,Date 等,就必须使用 == ,如果扩展的是类,则两者都可以使用,区别是如果使用 == 来约束,则扩展方法只对本类生效,子类无法使用。如果想要在子类也使用扩展方法,则使用 : 来约束。
2、静态方法,类方法可以通过加static关键词去拓展
3、如果对父类已经拓展实现了HDNameSpaceWrappable
协议,子类就不需要再实现了,会报错哦
参考文章
版权属于:东哥笔记 - DongGe.org
本文链接:https://dongge.org/blog/1077.html
自2017年12月26日起,『转载以及大段采集进行后续编辑』须注明本文标题和链接!否则禁止所有转载和采集行为!