修饰词
修饰词包括: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
    }
}