iOS多線程系統整理 swift

來源:互聯網
上載者:User

標籤:

多線程   是一個應用程式內多個代碼的執行路徑,執行線程,同時在同一時間裡執行不同的任務。

三種:

1、NSTread

2、Cocoa NSOperation (NSOperation,NSOperationQueue)

3、GrandCentralDispatch:GCD

1\NSTread

相對最簡單,需要自己管理線程的生命週期和線程同步(加鎖會有一定的系統開銷)

兩種應用方式:

需要傳遞三個參數:

selector:線程執行方法""

target:方法所在的對象

argument:傳遞給方法的參數,可選nil

 

一、直接建立線程,自動運行線程

// Class Method

class func detachNewThreadSelector(selector:Selector,toTarget target:AnyObject,withObject argument:AnyObject?)

二、先建立一個線程對象,手動運行線程,在運行之前可設定線程優先順序等資訊。

convenience init(target:AnyObject,selector:Selector,object argument:AnyObject?)

 

for example

// download image method

func downloadImage()

{

var imageUrl = "https://www.baidu.com/img/bdlogo.png"

var data = NSData.dataWithContentsOfURL(NSURL.URLWithString(imageUrl),options:nil,error:nil)

println(data.length)

}

 

override func viewDidLoad(){

super.viewDidLoad()

// 第一種方式

NSThread.detachNewThreadSelector("downloadImage",toTarget:self,withObject:nil)

 

// 第二種方式

var downloadImageThread = NSThread(target:self,selector:"downloadImage",object:nil)

dowloadImageThread.start()

}

線程同步,通過鎖來實現,每個線程有一個鎖,鎖 與 特定的線程關聯。

for example

// 定義兩個線程

var thread1,thread2:NSThread?

// 線程條件

let condition1 = NSCodition()

let condition2 = NSCodition()

// two method for thread 

func method1(sender: AnyObject)

{

  for var i = 0; i <10; i++

  {

  println("thread 1 running \(i)")

  sleep(1)

  if i == 2

  {

  thread2!.start()

// lock

condition1.lock()

condition1.wait()

condition1.unlock()

  }

  }

println(thread 1 over)

//

condition2.signal()

}

// 

func method2(sender:AnyObject)

{

  for var i=0;i<10;i++

  {

  println("thread 2 running \(i)")

  sleep(1)

  if i ==2

  {

//  active thread 1

  condition1.signal()

// lock 

condition2.lock()

condition2.wait()// stop waitting

condition2.unlock()

  }

  }

println("thread 2 over")

}

// RUN

thread2 = NSThread (target:self , selector:"method2:",object:nil)

thread1 = NSThread(target:self,selector:"method1",object:nil)

控制台輸出

thread 1 running 0

thread 1 running 1

thread 1 running 2

thread 2 running 0

thread 2 running 1

thread 2 running 2

thread 1 running 3

thread 1 running 4

thread 1 running 5

thread 1 running 6

thread 1 running 7

thread 1 running 8

thread 1 running 9

thread 1 over

thread 2 running 3

thread 2 running 4

thread 2 running 5

thread 2 running 6

thread 2 running 7

thread 2 running 8

thread 2 running 9

 

線程1 2是同步關係,啟動2,掛起 1,啟用1,掛起2,有效避免了線程1佔用一個資源時,引起線程2不能訪問的問題。

 

NSOperation 兩種方式

一  兩個子類 NSInvocationOperation   NSBlockOperation

// creat instance

var operation = NSInvocationOperation(target:self,selector:"dowloadImage",object:nil)

var queue = NSOperationQueue()

queue.addOperation(operation)

後台建立一個線程

Queue隊列中可以加入很多個operation 可以把它看做是一個線程池子,可以設定線程池中的線程數,即並行作業數。

預設是:-1,-1表示沒有限制,同時運行隊列中的全部操作。

queue.maxConcurrentOperationCount = 6

// ervery operation come to an end   

var completionBlock:(()->Void)?

operation.completionBlock = completionBlock

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,4),dispatch_get_main_queue(),{println("complete")})

 

// cancell

queue.cancelAllOperations()

 

二  繼承NSOperation   把子類的對象放到NSOperationQueue隊列中 ,一旦加入,就處理這個,直到操作完成,隊列被釋放。

// creat DrinkOperation.swift 繼承 NSOperation   且  實現main方法   

import UIKit

class DrinkOperation:NSOperation{

  override func main()

  {

  println("drink")

  }

 

// e.g.

// creat a  instance

var queue1 = NSOperationQueue()

// creat a operation

var drinkOperation = DrinkOperation()

// add 

queue1.addOperation(drinkOperation)

 

Grand Central Dispatch

多核編程

底層也是用線程實現,queue可以接受任務,先到先執行順序來執行,也可以並發或串列執行。

同步或非同步

優點多多:基於C,融入物件導向,Block,易用,效能上自動根據系統負載來增減線程數量,無需加鎖。

三種方法:

一 自己建立隊列

func dispatch_queue_create(label:UnsafePointer<Int8>,attr:dispation_queue_attr_t!)->dispatch_queue_t!

label:參數代表隊列名稱,可以任意名

DISPATCH_QUEUE_CONCURRENT  並行

DISPATCH_QUEUE_SERIAL 串列  

//e.g.

var serialQueue = dispatch_queue_create("serialQueue_1",DISPATCH_QUEUE_SERIAL)

var concurrentQueue = dispatch_queue_create("concurrentQueue_1",DISPATCH_QUEUE_CONCURRENT)

二  擷取系統的全域隊列

func dispatch_get_global_queue(identifier:Int,flags:UInt)->dispatch_gueue_t!

參數 identifier   執行優先順序  ,4個優先順序

DISPATCH_QUEUE_PRIORITY_HIGH

DISPATCH_QUEUE_PRIORITY_DEFAULT

DISPATCH_QUEUE_PRIORITY_LOW

DISPATCH_QUEUE_PRIORITY_BACKGROUND    非常低的有相機,用於不太關心的背景工作

// e.g.

var globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)

三 在主線程的Main dispatch queue

在主線程裡執行的隊列(只有一個主線程)

一切跟UI相關的操作都放到主線程中執行

func dispatch_get_main_queue()->dispatch_queue_t!

// e.g.

var mainQueue = dispatch_get_main_queue()

 

追加任務到隊裡的  兩個方法:
一 dispatch_async  非同步追加Block

async = asynchronous 非同步

func dispatch_async(queue:dispatch_queue_t!,block:dispatch_block_t!)

第一個參數:GCD隊列
第二個參數:block

// e.g.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),{()->Void in

//  耗時代碼塊

//執行完  調用主線程重新整理介面

dispatch_async(dispatch_get_main_queue(),{()->Void in

//通知主線程重新整理

 

})

})

 

二 dispatch_sync 同步追加Block

與之前相反,block結束之前,dispatch_sync會一直等待,等待隊列前面的所有任務完成後才執行追加的任務。

func dispatch_sync()

// e.g.

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),{()->Void in

println("sync1")

})

加到 global_queue非同步隊列中,不會造成鎖死,但會一直等待代碼執行完畢。

如果加到main_queue中,在主線程中新增工作操作,就會引起死結。

// e.g.

dispatch_sync(dispatch_get_main_queue(),{()->Void in

print("sync2")

})

 

暫停和繼續執行隊列

func  dispatch_suspend() 暫停

func dispatch_resume() 繼續

suspend  使 suspension reference count +1

resume    -1

count>0  queue就保持掛起狀態

如果掛起了  一個 queue   或者  source    那麼銷毀他之前,先對其進行恢複。

var concurrentQueue = dispatch_queue_create("concurrentQueue_1",DISPATCH_QUEUE_CONCURRENT)

// stop

dispatch_suspend(concurrentQueue)

// go on

dispatch_resume(concurrentQueue)

只執行一次 用於單例

dispatch_once

延時:指定時間後把任務追加到 dispatch queue裡面

dispatch_after

func dispatch_time(when:XX,delta:Int64)->dispatch_time_t

delta單位非常小,到秒要乘以  NSEC_PER_SEC

let deltaT = 2.0 *Double(NSEC_PER_SEC)

let  dTime =dispatch_time(DISPATCH_TIME_NOW,Int64(deltaT))

dispatch_after(dTime,dispatch_get_global-global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)

{()->Viod in

println("延時2秒執行")

})

 

多個任務都結束的一個全部結束:dispatch_barrier_async

當執行任務更新資料時,會出現資料不一樣的情況。

for i in 1...100

{

dispatch_async(queue,{()->Void in

println("\(i)")

 

})

}

雖然使用dispatch_barrier_async可以避免

但是有另一方法,  semaphore 訊號量

var semaphore = dispatch_semaphore_creat(1)//初始值為1

for i in 1...100

{

dispatch_async(queue,{()->Void in

 

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER)

println("\(i)")

dispatch_semaphore_signal(semaphore)

})

}

 

iOS多線程系統整理 swift

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.