修饰词
修饰词包括:private
、fileprivate
、internal
、public
、open
五种.其中fileprivate
和open
是Swift3
新加是对private
和public
的细分,区别如下:
private
:只能在当前源文件的当前类访问;
fileprivate
:在当前swift源文件能够访问;
internal
:默认,在这个源代码所在的模块或者整个APP代码均可访问.当是框架或者库代码则在这个框架内部可访问,外部引用时不能访问;
public
:公开的,能够呗任意处使用,但是其余module中不能被override和继承,在module内是可以的;
open
:任意处使用、override、继承
权限排序:open
>public
>interal
>fileprivate
>private
实用快捷键
作用: 隐藏方法的具体实现过程以及使用private
和fileprivate
修饰的类、方法和属性
快捷键: command + control + ↑/↓
Class 和 Struct
**相同点:** * 都能定义property、method、initalizers * 都支持protocol、extension **不同点:** [参考](https://juejin.cn/post/6844903775816155144) Class|Struct --|-- class是引用类型|struct是值类型 class支持继承|struct不支持继承 class声明的方法修改属性不需要mutating关键字|struct需要 class没有提供默认的memberwise initializer|struct提供默认的memberwise initializer class支持引用计数(Reference counting)|struct不支持 class支持Type casting|struct不支持 class支持Deinitializers|struct不支持
Class | Struct | |
相同点 | 都能定义property、method、initalizers 都支持protocol、extension |
|
不同点 | class是引用类型 | struct是值类型 |
class支持继承 | struct不支持继承 | |
class声明的方法修改属性不需要mutating关键字 | struct需要 | |
class没有提供默认的memberwise initializer | struct提供默认 | |
class支持引用计数(Reference counting) | struct不支持 | |
class支持Type casting | struct不支持 | |
class支持Deinitializers | struct不支持 |
Swift 扩展类的属性[Button]
在Swift
的Extension
里是不能添加存储属性的,这里可以类比Objective-C
的Category
分类,分类是不能添加实例变量和属性的.
因为不管是
Swift
的Extension
还是Objective-C
的Category
都不能改变原有的类或者结构体的内存结构,在实例化这些类的时候,内存结构是确定的,而添加属性或者实例变量需要内存空间,会改变原有的内存结构.
关联对象
在Objective-C
中我们常常用运行时Associated Object
关联对象来给Category
添加属性,而在Swift
里,我们同样可以利用关联对象在Extension
中添加计算属性,以达到所谓的存储属性的效果.
使用
// 按钮
let btn: UIButton = UIButton(type: .custom)
btn.setTitle("你好", for: .normal)
btn.frame = CGRect(x: 100, y: 100, width: 50, height: 30)
btn.layer.cornerRadius = 5
btn.addTarget(self, action: #selector(clickBtn), for: .touchUpInside)
btn.backgroundColor = .red
btn.clickType = .unfollow
btn.oneTest = "oooo"
self.view.addSubview(btn)
// 点击事件
@objc func clickBtn(_ sender:UIButton){
print("click-btn:\(sender.oneTest)")
print("click-btn:\(sender.clickType)")
}
// 输出
click-btn:oooo
click-btn:unfollow
扩展写法
extension UIButton {
enum btntype :Int{
case `default`
case follow
case unfollow
case other
}
struct RkBtnKey {
static var rkkey: String = "rk_btn_key"
static var rkkey1: String = "rk_btn_key1"
}
var clickType: btntype {
set {
objc_setAssociatedObject(self,&RkBtnKey.rkkey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
get {
if let action = objc_getAssociatedObject(self, &RkBtnKey.rkkey) as? btntype {
return action
}
return .default
}
}
var oneTest: String {
set {
objc_setAssociatedObject(self,&RkBtnKey.rkkey1, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
get {
return objc_getAssociatedObject(self, &RkBtnKey.rkkey1) as? String ?? "nil"
}
}
}
番外
关联策略|说明|对应属性
--|--|--
OBJC_ASSOCIATION_ASSIGN|给关联对象指定弱引用|@property(assign)
@property(unsafe_unretained)
OBJC_ASSOCIATION_RETAIN_NONATOMIC|给关联对象指定非原子的强引用|@property(nonatomic,strong)
@property(nonatomic,retain)
OBJC_ASSOCIATION_COPY_NONATOMIC|给关联对象指定非原子的copy特性|@property(nonatomic,copy)
OBJC_ASSOCIATION_RETAIN|给关联对象指定原子强引用|@property(atomic,strong)
@property(atomic,retain)
OBJC_ASSOCIATION_COPY|给关联对象指定原子copy特性|@property(atomic,copy)
关联策略 | 对应属性 |
---|---|
OBJC_ASSOCIATION_ASSIGN [弱引用] |
@property(assign) @property(unsafe_unretained) |
OBJC_ASSOCIATION_RETAIN_NONATOMIC [非原子的强引用] |
@property(nonatomic,strong) @property(nonatomic,retain) |
OBJC_ASSOCIATION_COPY_NONATOMIC [非原子的copy特性] |
@property(nonatomic,copy) |
OBJC_ASSOCIATION_RETAIN [原子强引用] |
@property(atomic,strong) @property(atomic,retain) |
OBJC_ASSOCIATION_COPY [原子copy特性] |
@property(atomic,copy) |
Swift 扩展类的属性[String]
使用
var ss: String? = nil
print("aaaaa===>\(ss.isBlank)")
if testStr.isEmpty {
print("str-empty")
}else{
print("str-no-empty")
}
ss = ""
let dic: [String:Any] = ["key1":ss]
/*
var aaa: Dictionary<String,Any?> = [:]
var bbb: [String:Any?] = [:]
var ccc = [String:Any]()
*/
print("hhhhhh:\(String.strFormat(dic["key1"]))")
写法
extension String {
var isBlank: Bool {
return allSatisfy({$0.isWhitespace})
}
/*
static func strFormat(_ original:Any) -> String {
if original is String {
let transStr = original as! String
if transStr.isBlank {
return ""
}else{
return transStr
}
}else{
return ""
}
}
*/
static func strFormat(_ original:Optional<Any>) -> String {
if original is String {
let transStr = original as! String
if transStr.isBlank {
return ""
}else{
return transStr
}
}else{
return ""
}
}
}
extension Optional where Wrapped == String {
var isBlank: Bool{
return self?.isBlank ?? true
}
}