Swift 基本语法(十一)— 泛型、多线程

//泛型编程是一种面向算法的多态技术
//协议关联类型 - 相当于泛型 associatedtype.  协议不支持泛型指定
/** 当协议里不知道该存储什么类型时, 使用一个关联类型占位的意思 */
protocol Container {
    associatedtype ItemType: Equatable //也可以给关联类型遵循协议
    mutating func append(_ item: ItemType)
    var count: Int {get}
    subscript(i: Int) -> ItemType {get}
}

extension Container {
    subscript<Indices: Sequence>(indice: Indices) -> [ItemType] where Indices.Iterator.Element == Int {
        var result = [ItemType]()
        for index in indice {
            result.append(self[index])
        }
        return result
    }
}

多线程

//多线程 Thread两种方法
for i in 0..<10 {
    Thread.detachNewThread {
        print(i)
    }
}

class TestThread {
    func threadFunction() -> Void {
        let thread = Thread(target: self, selector: #selector(threadFunc), object: nil)
        thread.start()
    }
    
    @objc func threadFunc() {
        print("Thread")
    }
}
//Operation  OperationQueue 简单使用。  和OC的很类似, 其他使用方法参考OC
class OperationClass {
    func blockOperation() -> Void {
        let op = BlockOperation {
            sleep(2)
            print("BlockOperation")
        }
        op.completionBlock = { [weak self] in
            print("Test + \(self)")
        }
        
        let op2 = BlockOperation(block: {[weak self] in
            sleep(1)
            self?.opFunc()
        })
        
        //operation执行完的回调
        op2.completionBlock = {
            print("都执行完了")
        }
        
        let queue = OperationQueue()
        queue.addOperation(op)
        queue.addOperation(op2)
    }
    
    func opFunc() -> Void {
        print("laile")
    }
}
let opClass = OperationClass()
opClass.blockOperation()
print("主线程开始执行")

//也可以继承自Operation
class MyOperation: Operation {
    override func main() {
        sleep(1)
        print("Custom Operation")
    }
}
GCD
//GCD
//这样简单创建的是串行队列
let serialQueue = DispatchQueue(label: "SerialQueue")

/**label: 队列标志名
 qos:一般选默认即可,  有background等模式
 attributes:指定串行还是b并发队列
 autoreleaseFrequency: 一般选继承类型即可inherit
 target:目标队列,可以不设置,系统会自动添加到目标队列里
 */
let queue = DispatchQueue(label: "MyQueue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
queue.sync {
    sleep(1)
    print("in queue sync")
}
print("after invoke queue method")
queue.async {
    sleep(1)
    print("in queue async")
}
print("after invoke queue method")
queue.asyncAfter(deadline: DispatchTime.now() + 1) {
    print("asyn after")
}
//GCD Group
let group = DispatchGroup()
let queue1 = DispatchQueue(label: "myQueue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
group.enter()
queue1.async {
    sleep(1)
    print("1111")
    group.leave()
}
group.enter()
queue1.async {
    print("22222")
    group.leave()
}
print("enter 完成")
//group.wait()
print("wait 是阻塞的,这个最后执行")

group.notify(queue: queue1) {
    print("12完成了")
}
print("Notify 是不阻塞的, 会先执行")
//DispatchSource - Timer
var seconds = 10
let queue = DispatchQueue(label: "MyQueue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)

let timer = DispatchSource.makeTimerSource(flags: DispatchSource.TimerFlags.init(), queue: queue)
timer.schedule(deadline: DispatchTime.now(), repeating: 1)
timer.setEventHandler {
    seconds -= 1
    if seconds < 0 {
        timer.cancel()
    }else {
        print(seconds)
    }
}
timer.resume()
//g多线程保证数组读写完全
class SafeArray {
    let queue1 = DispatchQueue(label: "queue1", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
    let queue2 = DispatchQueue(label: "queue2", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
    
        let arrayQueue = DispatchQueue(label: "arrayQueue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
    
    var largeArray = Array(0...10000)
    
//    let lock = NSLock()
//    func getLastItem() -> Int? {
//        lock.lock()
//        var temp = 0
//        if largeArray.count > 0 {
//            temp = largeArray[largeArray.count - 1]
//        }
//        lock.unlock()
//        return temp
//    }
//
//    func removeLastItem() -> Void {
//        lock.lock()
//        largeArray.removeLast()
//        lock.unlock()
//    }
    
    //更高效的获取方法
    func getLastItem() -> Int {
        arrayQueue.sync { () -> Int in
            var temp = 0
            if largeArray.count > 0 {
                temp = largeArray[largeArray.count - 1]
            }
            return temp
        }
    }
    //栅栏函数
    func removeLastItem() -> Void {
        let workItem = DispatchWorkItem(qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
            self.largeArray.removeLast()
        }
        arrayQueue.async(execute: workItem)
    }
    
    
    func testSafeArray() -> Void {
        queue1.async {
            for _ in 0...10000 {
                let index = self.getLastItem()
                print(index as Any)
            }
        }
        queue2.async {
            for _ in 0...10000 {
                self.removeLastItem()
            }
        }
    }
}

let safeArr = SafeArray()
safeArr.testSafeArray()

//栅栏函数使用
DispatchQueue.global().async(group: group, qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier) {
        
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267