从OC到Swift (二)

2022-01-29  本文已影响0人  冰棍儿好烫嘴

协议

只能被class继承的协议

protocol Runnable1: AnyObject{}
protocol Runnable2: class{}
@objc protocol Runnable3 {}
@objc protocol Runnable{
    func run1()
    @objc optional func run2()
    func run3()
}

class Dog: Runnable {
    func run1() { print("Dog run1")}
    func run3() {print("Dog runn3")}
}
var d = Dog()
d.run1()
d.run3()

dynamic

class Dog: NSObject {
    @objc dynamic func test1() {}//走runtime机制
    func test2() {}//走虚表一套流程
}
var d = Dog()
d.test1()
d.test2()

KVC/KVO

block方式的KVO

class Person: NSObject {
    @objc dynamic var age:Int = 0
    var observation:NSKeyValueObservation?
    override init() {
        super.init()
        observation = observe(\Person.age, options: .new, changeHandler: { person, change, in
            print(change.newValues as Any)
        })
    }
}

关联对象

protocol Runnable {
    
}
extension Runnable{
    
}
class Person:Runnable {
    var age = 0
}
extension Person{
    var weight = 0//报错:Extensions must not contain stored properties
}
  - 借助关联对象,可以实现类似`extension`为`class`增加存储属性的效果
extension Person{
    private static var AGE_KEY : Void?//这里用Void?或者bool类型,目的是为了省内存,Void?或者bool类型都只占用一个字节
    //类型存储属性,本质是全局变量
    var age:Int{
        get{
            objc_getAssociatedObject(self, &Person.AGE_KEY) as! Int
        }
        set {
            objc_setAssociatedObject(self, &Person.AGE_KEY, newValue, .OBJC_ASSOCIATION_ASSIGN)
        }
    }
}
var p = Person()
p.age = 10
print(p.age)

资源名管理

enum R{
    enum string:String {
        case add = "添加"
    }
    enum image:String {
        case logo
    }
    enum segue:String {
        case login_main
    }
}

let img = UIImage(named: R.image.logo.rawValue)
let btn = UIButton(type: .custom)
btn.setTitle(R.string.add.rawValue, for: .normal)
performSegue(withIdentifier: R.segue.login_main.rawValue, sender: self)

资源名管理的其他思路

enum R{
    enum image {
        static var logo = UIImage(named: "logo")
    }
    enum font {
        static func arial(_ size:CGFloat) -> UIFont?{
            UIFont(name: "Arial", size: size)
        }
    }
}

let img = R.image.logo
        let font = R.font.arial(14)

多线程开发 - 异步

//gcd
DispatchQueue.main.async {
      //拿到主线程
}
        
DispatchQueue.global().async {
     //拿到全局并发队列
     print(Thread.current)//打印当前线程
     DispatchQueue.main.async {
          //回到主线程
     }
}

或者:

let item = DispatchWorkItem{
    //子线程
    print("1",Thread.current)
}
DispatchQueue.global().async(execute: item)
item.notify(queue: DispatchQueue.main){
    //主线程
    
}

多线程开发 - 延迟

let time = DispatchTime.now()+3
        
DispatchQueue.main.asyncAfter(deadline: time){
     print("1")
}

多线程开发 - once

static var age:Int = getAge()
static func getAge() -> Int{
       print("getAge")
       return 0
}

print(Self.age)
print(Self.age)
print(Self.age)
//这种办法声明的getAge只会调用一次,即使是所在的ViewController被销毁之后重新创建,age也不会再走一遍初始化getAge的方法
fileprivate var initTask:Void = {
    print("init -------")
}()
let _ = initTask
let _ = initTask
//只走一次print("init -------")代码

多线程开发 - 加锁

import Foundation

public struct Cache{
    private static var data = [String:Any]()
    private static var lock = DispatchSemaphore(value: 1)//value值是几,就表示允许几条线程同时修改
    
    public static func get(_ key:String) -> Any?{
        data[key]
    }
    
    public static func set(_ key:String,_ value:Any){
        lock.wait()
        defer{lock.signal()}
        data[key] = value
    }  
}

或者:

import Foundation

public struct Cache{
    private static var data = [String:Any]()
    private static var lock = NSLock()
    
    public static func get(_ key:String) -> Any?{
        data[key]
    }
    
    public static func set(_ key:String,_ value:Any){
        lock.lock()
        defer {lock.unlock()}
        data[key] = value
    }
}

函数中有递归容易造成死锁,用递归锁解决

import Foundation

public struct Cache{
    private static var data = [String:Any]()
    private static var lock = NSRecursiveLock()
    
    public static func get(_ key:String) -> Any?{
        data[key]
    }
    
    public static func set(_ key:String,_ value:Any){
        lock.lock()
        defer {lock.unlock()}
        data[key] = value
    }
}
上一篇 下一篇

猜你喜欢

热点阅读