Swift-iOS实战笔记

134 阅读3分钟

属性

class Person {
    // 存储属性;可提供属性观察方法
    var age: Int = 0{
        willSet{
            print("即将将年龄从\(age) 设置为\(newValue)")
        }
        didSet{
            print("已经将年龄从\(oldValue) 设置为\(age)")
        }
    }
} 

willSetdidSet中,分别可以使用newValueoldValue 来获取将要设定的和已经设定的值。

  • 计算属性 计算属性则不包括背后的存储,只是提供set和 get 两种方法
class A {
    var number: Int {
        get{
            print("get")
            return 1
        }
        set{
            print("set")
        }
    }
} 

类型别名

别名的好处:增强阅读性

typealias Money = Int

struct Page {
    // 装 章的数组,元素是 页
    typealias Chapter = Array<Page>  
    // 装书的数组,元素是章
    typealias Book = Array<Chapter>
}

typealias Date = (year:Int, month:Int, day:Int)

typealias Success = (Int) -> Int
typealias Failure = (Error) -> Void
typealias Progress = (Double) -> Void

func handle2(success: Success?, failure: Failure?, progress: Progress?) { 
// ... 
}

/////
final class Dispatcher {  
    typealias Success = (Int, HTTPResponse) -> Void  
    typealias Failure = (Error, HTTPResponse) -> Void  

    private var successHandler: Success?  
    private var errorHandler: Failure?    

    func handle(success: Success?, error: Failure?) {  
        self.successHandler = success    
        self.errorHandler = error    
        internalHandle()  
    }    

    func handle(success: Success?) {   
	self.successHandler = success    
	internalHandle()  
    }    

    func handle(error: Failure?) {    
	self.errorHandler = error    
	internalHandle()
    }    

    private func internalHandle() {   
	// ...  
    }
}


泛型类型别名

typealias MyArray<T> = Array<T> where T: StringProtocol
// MyArray类型的数组 只装遵循StringProtocol协议的元素

单例模式

方式一

final class Users: NSObject {
    // 静态变量,内存空间不释放
    static let shared = Users()
    
    // 一定要加private防止外部通过init直接创建实例
    private override init() {
        
    }
}

方式二

代理/协议

声明协议

@objc
protocol HomeHeaderViewDelegate: class {
    associatedtype Money  // 声明一个泛型类型(Money具体什么类型在使用时 确定)

    func dataDidUpdate() -> Money
    
     // 代理方法(可选)
    @objc optional func headerView(_ headerView: UIView, didSelectItemAt index: Int)
    // (必须)
    func headerViewDidUpdate(_ headerView: UIView )
}

给view 代理属性


class HomeHeaderView: UIView {
    
    // 代理属性 weak修饰
    open weak var delegate: HomeHeaderViewDelegate?

    // .......    

    // 点击触发,代理对象执行 代理方法
    delegate?.headerView?(self, didSelectItemAt: index)
}

VC遵守协议,设置代理,实现代理方法

lazy var header: HomeHeaderView = {
    let v = HomeHeaderView.init()
    v.delegate = self   // 设置代理
    return v
}()

extension HomeController : HomeHeaderViewDelegate{
    func headerView(_ headerView: UIView, didSelectItemAt index: Int) {
        let mo = self.header.banners![index]
        debugPrint("xxxxxx")
    }
}

协议中的关键字associatedtype

associatedtype用来定义一个 在协议中的泛型类型。定义为 associatedtype类型的,在实现协议的类中使用的时候,指明该类型的具体类型是什么 即可

协议的扩展extension

可以给协议添加新的函数等,另外可以给协议内部的函数添加 默认实现。

protocol PersonProtocol {
    @objc optional var age: Int { get set}
    
    @objc optional func dowork()
}

// 协议扩展
extension PersonProtocol {
    // 默认协议方法实现
    func dowork(){
        print("我想上厕所")
    }
    // 新增协议方法
    func run() {
    
        print("我在跑步")
    }
}

通知的使用

监听通知

NotificationCenter.default.addObserver(self, selector: #selector(clickFunc), name: NSNotification.Name.init(rawValue: "xxxName"), object: nil)

//......

// 通知响应方法
@objc func clickFunc(note: NSNotification) {
    if let b = note.userInfo?["tag"] as? NSNumber, b == 2 {
            
    }
}

发送通知

NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "xxxName"), object: nil, userInfo: ["tag": 11])

闭包

声明闭包类型,使用时相当于 一个普通类型如:Int、String等,可作为函数入参

typealias actionCallback = (() -> Void)

typealias SwiftBlock = (String,Any) -> Void

调用

actionCallback? ()

testBlock?("ddd","ffffff")

// ps: 不用if判断,那是OC的风格

防止循环引用

{ [weak self] (a,b) in
        
    print(a)
    print(b)
}

// [weak self]是为了防止循环引用,(a,b)是传过来的参数

逃逸闭包

就是闭包作为函数的参数,但是在函数结束以后,才去执行这个参数的就叫逃逸闭包。在参数类型前加@escaping

定时器

Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in
        debugPrint("mm")
}

###动画

UIView.animate(withDuration: 2, animations: {
            
}) { (end) in
            
}

线程

主线程异步任务

DispatchQueue.main.async {
            
}

延迟执行

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0) {
            
}
self.perform(#selector(popViewController), with: nil, afterDelay: 2.0)

@objc func popViewController(){
  
}

后台执行

self.performSelector(inBackground: #selector(popViewController), with: nil)

子线程执行方法

self.perform(#selector(doSomething))

关联对象

给类添加新的属性

struct RunTimeViewKey {
    static let RunTimeViewID = UnsafeRawPointer.init(bitPattern: "RunTimeViewID".hashValue)
}

extension UIView {
    var ViewID: String? {
        set {
            objc_setAssociatedObject(self, RunTimeViewKey.RunTimeViewID!, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
       
        }
        get {
            return  objc_getAssociatedObject(self, RunTimeViewKey.RunTimeViewID!) as? String
        }
    }
    
}