category
swift
@interface ClassName (CategoryName)
@end
extension 又被称为匿名分类(anonymous category)
swift
@interface ClassName ()
@end
可以在 extension 的{}
中添加自定义的实例变量
swift
@interface XYZPerson () {
id _someCustomInstanceVariable;
}
...
@end
主要区别
- Category是运行时 决定生效的,Extension是编译时就决定生效的
- Category可以为系统类添加分类,Extension不能。
- Category是有声明和实现,Extension直接写在宿主.m文件,只有声明。
- Category只能扩充方法,不能扩充成员变量和属性。
- 如果Category声明了一个属性,那么Category只会生成这个属性的set,get方法的声明,也就不是会实现 get set 方法。属性的实例变量无法被存储,除非是原有类的实例变量。
- 如果我们在 extension 中添加了方法, 那么这些方法必须在类的实现中实现。
参考:https://juejin.cn/post/6960972413240606734
swift 不能在 extension 中添加存储属性,但可以通过 AssociatedKey 的方式来间接实现。
swift
public extension UIView {
private struct AssociatedKey {
static var identifier: String = "identifier"
}
public var identifier: String {
get {
return objc_getAssociatedObject(self, &AssociatedKey.identifier) as? String ?? ""
}
set {
objc_setAssociatedObject(self, &AssociatedKey.identifier, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
}
}
}
参考:https://juejin.cn/post/6856416734577410055
swift 的 extension 相当于影分身,每个分身可以具有不同技能(遵循了某个协议或数据源或新定义一下方法)
swift 的 category 写法:extension name
on SomeClass
swift
extension SomeName on DateTime {
}