Swift的命名空间是以模块来划分的,一个模块表示一个命名空间,我们进行APP开发是,默认添加到主target的内容是同处于同一个命名空间的。如果用Cocoapod的方式导入的第三方库,是以一个单独的target存在,不会存在命名冲突。如果是以源码的方式导入工程中,很有可能发生命名冲突。所以,为了安全起见,第三方库都会使用命名空间这种方式来防止冲突。在Objective-C上没有命名空间,一般是使用方法名前面加前缀的方式避免冲突。
以下是图片加载库Kingfisher的命名空间实现方式
public struct KingfisherWrapper<Base> {
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
/// Represents an object type that is compatible with Kingfisher. You can use `kf` property to get a
/// value in the namespace of Kingfisher.
public protocol KingfisherCompatible: AnyObject { }
/// Represents a value type that is compatible with Kingfisher. You can use `kf` property to get a
/// value in the namespace of Kingfisher.
public protocol KingfisherCompatibleValue {}
extension KingfisherCompatible {
/// Gets a namespace holder for Kingfisher compatible types.
public var kf: KingfisherWrapper<Self> {
get { return KingfisherWrapper(self) }
set { }
}
}
extension KingfisherCompatibleValue {
/// Gets a namespace holder for Kingfisher compatible types.
public var kf: KingfisherWrapper<Self> {
get { return KingfisherWrapper(self) }
set { }
}
}
extension UIImage: KingfisherCompatible { }
extension UIImageView: KingfisherCompatible { }
extension UIButton: KingfisherCompatible { }
上段代码已经定义了命名空间:“kf”
以下是kf命名空间内添加方法,并使用
extension KingfisherWrapper where Base: Image {
//为UIIMage动态添加animatedImageData属性
private(set) var animatedImageData: Data? {
get { return getAssociatedObject(base, &animatedImageDataKey) }
set { setRetainedAssociatedObject(base, &animatedImageDataKey, newValue) }
}
//为UIIMage动态添加scale计算属性
var scale: CGFloat {
return 1.0
}
//使用:
let img = UIImage()
let scale = img.kf.scale //获取kf命名空间下的scale属性
在学习swift中发现,Data类型在swift中也是值类型
swift中值类型除了数值类型外,Array, Dictionary, String , Data, Struct, Enum 均为值类型
Mark:之后有时间做详细解释
网友评论