[ SWIFT ] - 史丹福 StandFord-CS193P-課程9-心得分享-20150824
[ SWIFT ] - 史丹福 StandFord-CS193P-課程9-心得分享-20150824
課程重點:
(1)Scroll View-滾動視圖 、(2)Closures-閉包-非常重要、(3)Multithreading-多緒
(a)透過ContentSize宣告ScrollView的區域
(b)宣告ScrollView frame的範圍
ScrollView結果呈現:
實際背景情況
(1.2)透過contentoffset來取得Scroll View目前的位置
(1.3)透過convertRect取得目前顯示範圍得座標,scrollview得bound
(1.4)新增ScrollView得3種方法
下圖為從Embed中新增Scroll View位置
老師再次提醒大家,使用Scroll View時別忘了!宣告contentSize
(1.6)Zooming得設定
預設值為1,minimumZoomScale:最小倍率值,maximumZoomScale:最大倍率值
※使用Zooming功能時需要使用delegate,因此在viewcontroller中別忘了加上UIScrollView!
scrollViewDidEndZooming:在每次滾軸視圖的ContentOffset改變時都會被調用,當用戶在四周移動手指時也會一直被調用
(2.1)閉包得特性:可以捕捉閉包中所使用的外部變數!
(2.2)使用閉包可以讓程式碼更簡潔!
※有關closures得使用在[ SWIFT ] - 史丹福 StandFord-CS193P-課程3-心得分享-20150723已有提過!
有關Closures得介紹請參考:The Swift Programming Language中的介紹
有關closures得幾種寫法-強烈推薦
http://gradyzhuo-swift.logdown.com/posts/210954-closure
範例:
(2.3)使用Closures得風險:造成資料永遠存在記憶體中!
Main Queue絕對不能做任何可能阻塞包含URL的NSData
let queue: dispatch_queue_t =要想做的隊列 //隊列
dispatch_async(queue){做想做的事情}
The Main queue
let mainQ:dispatch_queue_t = dispatch_get_main_queue //返回主隊列
let mainQ: NSOperationQueue = NSOperationQueue.mainQueue() //面向對象的方法
dispatch_async(notTheMainQueue){
dispatch_async(dispatch_get_main_queue()){}
}
要創建一個非主隊列,首先要創建一個服務級別,創建級別的方 法有點奇怪,使用了一個Int的構造器,構造其中選擇級別的value屬性,這種做法是由歷史原因造成的。在創建好級別之後,使用 dispatch_get_global_queue函數,傳入級別和一個0,這個0以後會用到。有了新的隊列,你就可以使用 dispatch_asnyc函數並且在非主隊列中執行代碼了。
如果有多核處理器,隊列真的可以並行運行,但是大部分情況下他們是分時的。你可以創建自己的串行隊列,使用dispatch_queue_create來建立一個串行的隊列。
下面介紹一些主隊列之外的其他隊列,這些隊列通常使用不同的處理級別來表示,處理級別的高低也代表了隊列不同的處理速度。
QOS_CLASS_USER_INTERACTIVE //快速並且優先級高
QOS_CLASS_USER_INITIATED //優先級高,但是需要時間
QOS_CLASS_UTILITY //需要較長時間執行的工作,例如:資料庫同步或大量資料運算
QOS_CLASS_BACKGROUND //用戶不需要知道的背景工作,例如:預先下載圖片
有時為了保護代碼可以設定主線程停頓幾秒後再執行!
確認主線程是否阻塞
在iOS中有些API是多線程的,比如下面這個例子:
在範例中的NSURLSession(注意黃色字體的部分),負責從一個URL中以異步方式下載一個文件。在方法後面增加了一個閉包,這個閉包的作用是當你下載完畢時你需要在UI中打開這個文件,閉包為你指定了一個本地URL,一個HTTP回復了一個錯誤信息,利用這些信息你會做一些更新UI的事情。那麼這樣做是否行得通?答案是「NO」。
因為這個下載的文件不在主隊列中,解決辦法是在閉包中打開主隊列:
課程重點:
(1)Scroll View-滾動視圖 、(2)Closures-閉包-非常重要、(3)Multithreading-多緒
(1)Scroll View-滾動視圖的介紹
(1.1)Scroll View的組成-ContentSize(宣告滾動範圍)+frame(設定顯示範圍):(a)透過ContentSize宣告ScrollView的區域
(b)宣告ScrollView frame的範圍
ScrollView結果呈現:
實際背景情況
(1.2)透過contentoffset來取得Scroll View目前的位置
(1.3)透過convertRect取得目前顯示範圍得座標,scrollview得bound
(1.4)新增ScrollView得3種方法
下圖為從Embed中新增Scroll View位置
老師再次提醒大家,使用Scroll View時別忘了!宣告contentSize
(1.6)Zooming得設定
預設值為1,minimumZoomScale:最小倍率值,maximumZoomScale:最大倍率值
※使用Zooming功能時需要使用delegate,因此在viewcontroller中別忘了加上UIScrollView!
scrollViewDidEndZooming:在每次滾軸視圖的ContentOffset改變時都會被調用,當用戶在四周移動手指時也會一直被調用
(2)Closures-閉包
介紹:(2.1)閉包得特性:可以捕捉閉包中所使用的外部變數!
(2.2)使用閉包可以讓程式碼更簡潔!
※有關closures得使用在[ SWIFT ] - 史丹福 StandFord-CS193P-課程3-心得分享-20150723已有提過!
有關Closures得介紹請參考:The Swift Programming Language中的介紹
有關closures得幾種寫法-強烈推薦
http://gradyzhuo-swift.logdown.com/posts/210954-closure
範例:
(2.3)使用Closures得風險:造成資料永遠存在記憶體中!
(3)Multithreading-多緒
在IOS中存在許多隊列,每個列隊都由自己的線程進行處理(採先進先出),其中最重要得隊列為:主隊列,主隊列是一個串行隊列,所以主隊列只會一個一個地執行主隊列中的函數。所有的UI活動都必須發生在主隊列中。
在app運作的過程中,我們透過函數或是閉包得使用,讓UI產生變化,在使用的過程中就必須把它放到主隊列中,這是保護UI的好辦法,主隊列絕對不想做任何可能被阻塞的事情,此部份請思考:如果app運作過程中出現阻塞(也就是任何得等待情況),那麼最好的作法就是將他從主隊列中移至其他隊列中,例如:當我們從網路中下載一個較大的圖片時,系統會因為等待下載造成主隊列阻塞!那麼較好得作法就是,將下載動作從主隊列中拿出來,讓主隊列可以正常執行其他功能!
通常你使用MVC中的東西都在主隊列中,比如頁面生命週期中的ViewDidLoad、viewWillAppear,我們不需要特別的留心。
通常你使用MVC中的東西都在主隊列中,比如頁面生命週期中的ViewDidLoad、viewWillAppear,我們不需要特別的留心。
如何在其他隊列中執行函數或者閉包呢?
(3.1)初始化隊列-dispatch_async:
透過dispatch_async進行初始化隊列,dispatch_async有兩個參數,第一個是隊列,第二個是一個閉包(這裡得閉包採尾隨閉包的寫法)。
問題:隊列執行完後如何返回主隊列呢?
透過dispatch_get_main_queue(),就能返回主隊列了。
此外也可透過:NSOperationQueue.mainQueue()。返回主隊列!
重點彙總:
Main Queue 主隊列是個串行隊列,所有的UI活動都必須方法在主隊列Main Queue絕對不能做任何可能阻塞包含URL的NSData
let queue: dispatch_queue_t =要想做的隊列 //隊列
dispatch_async(queue){做想做的事情}
The Main queue
let mainQ:dispatch_queue_t = dispatch_get_main_queue //返回主隊列
let mainQ: NSOperationQueue = NSOperationQueue.mainQueue() //面向對象的方法
dispatch_async(notTheMainQueue){
dispatch_async(dispatch_get_main_queue()){}
}
要創建一個非主隊列,首先要創建一個服務級別,創建級別的方 法有點奇怪,使用了一個Int的構造器,構造其中選擇級別的value屬性,這種做法是由歷史原因造成的。在創建好級別之後,使用 dispatch_get_global_queue函數,傳入級別和一個0,這個0以後會用到。有了新的隊列,你就可以使用 dispatch_asnyc函數並且在非主隊列中執行代碼了。
如果有多核處理器,隊列真的可以並行運行,但是大部分情況下他們是分時的。你可以創建自己的串行隊列,使用dispatch_queue_create來建立一個串行的隊列。
下面介紹一些主隊列之外的其他隊列,這些隊列通常使用不同的處理級別來表示,處理級別的高低也代表了隊列不同的處理速度。
QOS_CLASS_USER_INTERACTIVE //快速並且優先級高
QOS_CLASS_USER_INITIATED //優先級高,但是需要時間
QOS_CLASS_UTILITY //需要較長時間執行的工作,例如:資料庫同步或大量資料運算
QOS_CLASS_BACKGROUND //用戶不需要知道的背景工作,例如:預先下載圖片
確認主線程是否阻塞
在iOS中有些API是多線程的,比如下面這個例子:
在範例中的NSURLSession(注意黃色字體的部分),負責從一個URL中以異步方式下載一個文件。在方法後面增加了一個閉包,這個閉包的作用是當你下載完畢時你需要在UI中打開這個文件,閉包為你指定了一個本地URL,一個HTTP回復了一個錯誤信息,利用這些信息你會做一些更新UI的事情。那麼這樣做是否行得通?答案是「NO」。
因為這個下載的文件不在主隊列中,解決辦法是在閉包中打開主隊列:
Activity Indicator View
透過activity indicator view呈現運作畫面,讓使用者了解目前正在運作中。
startAnimating():表示開始呈現
stopAnimating():表示停止呈現
透過show可設定 activity indicator view得呈現效果,是否要淡入淡出
當activity indicator view與imageview重疊時,可透過document outline進行拖拉或是直接設定約束條件。
留言
張貼留言
您好:
歡迎到訪我的Blog,這裡有我的生活經驗、美好的回憶和程式開發經驗分享~
目前努力學習Swift中,希望你會喜歡Swift!
如果可以也請你留言給我一個鼓勵喔!
謝謝