A. Web前端開發與iOS終端開發的異同
語言
前端和終端作為面向用戶端的程序,有個共同特點:需要依賴用戶機器的運行環境,所以開發語言基本上是沒有選擇的,不像後台想用什麼就用什麼,iOS只能用Objective-C,前端只能javascript,當然iOS還可以用RubyMotion,前端還能用GWT/CoffieScript,但不是主流,用的人很少,真正用了也會多出很多麻煩。
這兩者有個有意思的對比:變數/方法命名的風格正好相反。蘋果一直鼓吹用戶體驗,寫代碼也不例外,程序命名都是用英文全稱並且要多詳細有多詳細,力求看變數和方法名就能知道是幹嘛的,例如application:didFinishLaunchingWithOptions:。而js因為每次都要從網路下載,要力求減少代碼體積,所以變數方法名是盡量用縮寫,實際上有代碼壓縮工具,無論變數名寫多長最終上線的效果是一樣的,但大家也都習慣了用短的命名,例如上述objc的application:didFinishLaunchingWithOptions:方法在js里習慣的命名是:$()。
objc與js都是動態語言,使用起來還蠻像,但objc是編譯型,速度快,很多錯誤也能在編譯過程中被發現,js是解釋型,性能依賴於解釋引擎,即使在強勁的v8引擎下性能也趕不上編譯型語言,語言太動態,變數完全沒有類型,寫起來爽,debug起來稍微費點勁。一直感覺js輕巧靈活放盪不羈充滿各種奇技淫巧,objc中規中矩沒c++ java那麼嚴肅也沒有js那麼靈活。
線程
前端開發幾乎不需要線程這個概念,瀏覽器實現上頁面HTML和CSS解析渲染可能與js不在同一個線程,但所有js代碼只執行在一條線程上,不會並發執行,也就不需要考慮各種並發編程的問題。在新的JS特性中可以創建worker任務,這樣的任務是可以另起一條線程並行執行的,但由於並不是所有瀏覽器都支持,不同線程傳遞數據各個標準定的還不一樣,使用場景也少,似乎沒有大規模用起來。對於資料庫操作/發送網路請求這樣的任務是在不同於js代碼執行線程的,不過這些都由瀏覽器管理,前端無需關心也無法影響這些線程,只需接收事件回調,不需要處理任何並發問題。
終端開發需要大量使用多線程,iOS有一條主線程,UI渲染都在這個線程,其他耗時長的邏輯或者資料庫IO/網路請求都需要自己另開線程執行,否則會佔用主線程的時間,導致界面無法響應用戶交互事件,或者渲染慢導致滾動卡頓。程序邏輯分布在多個線程里跑,需要處理好各種代碼並發執行可能帶來的數據不一致/時序錯亂之類的問題,並發也導致有些bug難以排查,一不留神就掉坑,需要適當用一些隊列/鎖保證程序的執行順序。iOS提供了一套多線程管理的方法GCD,已經把線程和隊列封裝得非常簡單易用功能強大,比其他端或後台是好很多了,但還是會花大量功夫在處理多線程問題上。
存儲
終端開發需要大量的數據存儲邏輯,手機APP不像瀏覽器,用戶打開瀏覽器必定是連著網,但打開一個APP時很可能是離線,也很可能處於網路狀況極差的移動GPRS,所以必須把之前請求回來的數據保存好。保存數據後又需要與服務端最新的數據同步,如果全量同步數據量太大,耗流量速度也慢,於是需要增量同步,需要與服務端一起制定實現增量數據返回的方案,需要處理好客戶端與服務端數據一致性的問題。當數據存儲量大結構復雜時,還需要利用好有限的內存做cache,優化各類存儲查詢性能。
前端在桌面端很少需要存儲,除非是Single Page App,不存儲自然就不需要數據更新的一系列工作,數據都是從後台取出拼接後直接顯示到頁面上,即使像微博有可以在頁面內不斷載入更多數據,數據也只存在於內存,不會持久化存儲,因為桌面端網速穩定,不計流量,所有數據可以直接從後端拿取,客戶端沒必要再做一套存儲。移動端那些做得很像原生APP的Web應用就跟終端開發一樣了,數據同樣保存到SQLite,存儲邏輯以及要處理的問題都差不多。
框架
在第三方框架上Web前端和iOS開發完全相反,Web原生弱小又十分開放,讓大量第三方框架和類庫可以施展拳腳,而iOS原生強大又十分封閉,導致第三方框架沒有多少生存空間。
瀏覽器一開始只為內容型的網頁而設計,js也只是這個網頁上能加點小特效的腳本語言,在Web應用時代跟不上發展,需要很多第三方庫和框架輔助,再加上前端開發是完全開放的領域,導致庫和框架百花齊放多如牛毛,在初期多數庫的作用集中在封裝dom操作,大家不斷重復造dom操作基礎庫的輪子,在一段時間百家爭鳴後獨尊jQuery,在有使用庫的網站中90%以上使用jq,幾乎成了個標准基礎庫。後期大家已經不再重復造這個基礎庫的輪子了,多了一些代碼組織和前端架構的框架,例如一些幫助項目模塊化的框架require.js,MVC框架backbone/angular.js等。
iOS開發蘋果已提供了完整的開發框架cocoa,而這框架在每一代系統中都在升級優化和添磚加瓦,開發模式也已經定型,第三方框架沒有多少生存空間,大量流行的開源項目是一些通用組件和庫,像網路請求庫AFNetworking,資料庫操作庫FMDB。而一些大的框架像beeFramework/ReactiveCocoa較難流行起來。
兼容
前端開發需要兼容大——量的瀏覽器,桌面的chrome,safari,ie6-ie10,firefox,以及各種套殼獵豹360等瀏覽器,移動端iOS/Android各自的瀏覽器,以及無限的不同的屏幕尺寸。看起來挺可怕,實際上也沒那麼難搞,只是拿出來嚇唬下人。桌面端chrome/safari以及各種套殼的極速模式用的都是Webkit,差異很小,firefox也大體遵從標准實現,與Webkit差別不大,舊的ie6/7就需要特別照顧,不過很多網站都不支持ie6了,移動端更是一家親,全是Webkit,除了新特性上的支持程度不一,其他差異不大。對於不同的屏幕尺寸,高端點的會用響應式布局,針對不同屏幕尺寸自適應到不同布局,一般點的桌面端定死寬度,移動端拉伸自適應寬度就搞定。
終端開發也需要兼容各種不同的系統版本和手機尺寸,Android不用說,iOS也有3.5/4/4.7/5.5/9.7英寸這些尺寸,不過兼容起來跟Web一樣挺容易,就是自適應寬度,iOS的UIKit把這些都處理好了,還有autolayout,sizeClass等高級特性可用,在尺寸上並不用花太多功夫。系統版本上iOS7為分水嶺,iOS7前後版本UI上差異比較大,需要做一些功夫兼容,不過iOS用戶更新換代很快,預計再過一兩年iOS7以下用戶就可以忽略了。
性能
終端和前端都是面向用戶的,性能優化目的都是盡快呈現內容,以及讓程序在用戶操作下流暢運行。終端主要關注的是存儲/渲染性能。當一個APP存儲數據量大,數據關系復雜時,數據查詢很容易成為性能瓶頸,需要不斷優化數據存取的效率,規劃數據IO線程,設計內存cache,利用好終端設備有限的內存,渲染上避免重復渲染,盡可能復用視圖,尋找最高效的渲染方案。
前端關注頁面載入速度,由於Web頁面的結構/樣式/程序/資源圖片都是實時請求的,要讓頁面更快呈現內容,就要優化這些請求,讓這些資源以最快速度載入下來,包括合並圖片/合並代碼減少請求數,壓縮代碼,並行請求,根據版本號緩存代碼請求,gzip壓縮,模塊/圖片懶載入等。此外跟終端一樣也關注渲染性能,遵從一些規則避免頁面reflow,避免使用CSS陰影這樣耗性能的特效,用CSS3動畫代替js等。
編譯
終端開發需要編譯的過程,把程序編譯成機器語言,再與各種庫鏈接後生成平台對應的可執行文件,最後由操作系統調度執行。在iOS終端開發中編譯和鏈接的規則蘋果已經在xcode這個開發工具上封裝好,一般開發可以不用關心,但有深層需求時還是需要跟編譯打很多交道,例如用編譯前端Clang自定義靜態代碼檢測規則,寫編譯腳本做自動化編譯和持續集成,打包生成靜態庫,根據鏈接後的可執行文件的組成優化APP體積等。
前端開發的程序則不需要編譯過程,只需要把代碼扔給瀏覽器,瀏覽器邊解析代碼邊執行。雖然js/css代碼寫完無需做任何事情瀏覽器就可以解析執行,但為了上面說的性能優化,前端代碼上線前會對所有代碼和資源文件進行處理,這些處理包括:壓縮合並js/css,合並css sprite圖,處理模塊依賴,處理代碼資源版本號,處理資源定位等。這個過程很像傳統程序的編譯,把給人看的代碼優化處理成給機器看的,並解決一些依賴關系,可以算是前端的編譯過程。像grunt.js/fis這些工具可以幫助完成這個編譯過程,通常前端編譯跟上線部署結合在一起,作為上線系統的一部分。
安全
前端和終端的安全性問題上雖然不需要像後端考慮得那麼多,但還是有些需要注意。在請求的安全上,終端和前端都一樣,用戶向後端發送的請求都需要經過層層路由,不知道在哪裡就被截獲篡改或回放了,於是需要做一些措施防禦這些情況,最常見的就是身份驗證,多是採用會過期的token形式代替用戶名密碼,防止被抓包後黑客可以永遠登陸這個賬號。數據安全要求高的會用加密傳輸,或者使用https,另外還需要看情況處理一些DNS劫持,運營商廣告植入等問題。
其他安全問題終端很少考慮,在未越獄的iOS機器上系統已經幫忙保證了整個APP運行環境的安全,而在越獄的機器下惡意程序擁有root許可權可以做任何事情,APP也難以防範。前端方面瀏覽器的特性使前端開發有幾個安全隱患,一是Web頁面上任意位置都可以動態插入js代碼,瀏覽器會無區別地執行這些代碼,二是身份驗證信息都統一保存在cookie里,三是頁面上可以隨意通過iframe嵌入其他網站的頁面。造成XSS、CSRF、cookie劫持這些攻擊手段,所以前端寫代碼時都需要考慮還這些安全問題,做好相應的防範,最簡單和重要的防範就是對所有用戶輸入輸出的內容做完整的過濾,避免頁面內被嵌入惡意代碼。
交互/開發
最後說下對這兩個領域在交互和開發上的個人感觸。以前在做Web前端時,感覺Web讓人機交互倒退了十年,交互都是硬邦邦的點擊—啪一下出來結果,滾動是一格格地刷新,很多人當時在鼓吹html5可以做出多麼炫的效果時,實際上FLASH在十年前就可以做出來了,還比最現代的瀏覽器更流暢。iPhone流行後,人機交互終於恢復了應有的水平,體驗上比Web流暢太多,指尖交互/流暢的動畫/便捷的滑動手勢/無限制的實現,主流終於恢復或超越了十年前Flash的水平。
但人機交互提升了,開發方式卻大倒退,Web的開發方式非常先進,用戶用到的都是最新版本,發現bug可以馬上上線秒修復,特別適用於互聯網環境下的快速迭代,而終端APP不行,撇開iPhone的審核不說,Android也無法做到保證用戶用的是最新的程序,用的都是傳統的客戶端更新的方式,bug的修復版無法及時給到用戶,無法一天上線幾十次,需要維護很多舊版本,開發方式倒退回Web時代以前。這都是因為移動網路不穩定以及流量有限造成的,移動端無法像桌面端瀏覽器那樣完全依賴網路,所以在移動網路穩定流量免費之前,開發方式都不會有多大變化。
另外並不看好HTML5,網路上說它可以取代APP說了三四年,到現在也沒什麼戰績,我看不到它的優勢,原生APP可以獲得更多的系統資源,更流暢的人機交互體驗,HTML5在這方面永遠比不上,而它在移動端網路和流量的限制下也無法發揮Web的開發優勢,所以它不會成為主流,只適合做一些輕量的小東西。
B. Java並發編程(二)為什麼需要多線程
*使用線程可以把占據時間長的程序中的任務放到後台去處理
*程序的運行速度可能加快
*在一些等待的任務實現上如用戶輸入、文件讀寫和網路收發數據等,線程就比較有用了。在這種情況下可以釋放一些珍貴的資源如內存佔用等等。
*多線程技術在IOS軟體開發中也有舉足輕重的位置。
C. 如何設置兩個方法之間的依賴關系 ios
iOS Concurrency Programming Guide
iOS 和 Mac OS 傳統的並發編程模型是線程,不過線程模型伸縮性不強,而且編寫正確的線程代碼也不容易。Mac OS 和 iOS 採取 asynchronous design approach 來解決並發的問題。
引入的非同步技術有兩個:
Grand Central Dispatch:系統管理線程,你不需要編寫線程代碼。只需定義想要執行的任務,然後添加到適當的dispatch queue。Grand Central Dispatch會負責創建線程和調度你的任務。系統直接提供線程管理,比應用實現更加高效。
Operation Queue:Objective-C對象,類似於dispatch queue。你定義想要執行的任務,並添加任務到operation queue,後者負責調度和執行這些任務。和Grand Central Dispatch一樣,Operation Queue也管理了線程,更加高效。
Dispatch Queue
基於C的執行自定義任務機制。dispatch queue按先進先出的順序,串列或並發地執行任務。serial dispaptch queue一次只能執行一個任務,直到當前任務完成才開始出列並啟動下一個任務。而concurrent dispatch queue則盡可能多地啟動任務並發執行。
優點:
直觀而簡單的編程介面
提供自動和整體的線程池管理
提供匯編級調優的速度
更加高效地使用內存
不會trap內核under load
非同步分派任務到dispatch queue不會導致queue死鎖
伸縮性強
serial dispatch queue比鎖和其它同步原語更加高效
Dispatch Sources
Dispatch Sources 是基於C的系統事件非同步處理機制。一個Dispatch Source封裝了一個特定類型的系統事件,當事件發生時提交一個特定的block對象或函數到dispatch queue。
你可以使用Dispatch Sources監控以下類型的系統事件:
定時器
信號處理器
描述符相關的事件
進程相關的事件
Mach port事件
你觸發的自定義事件
Operation Queues
Operation Queues是Cocoa版本的並發dispatch queue,由 NSOperationQueue 類實現。dispatch queue總是按先進先出的順序執行任務,而 Operation Queues 在確定任務執行順序時,還會考慮其它因素。最主要的一個因素是指定任務是否依賴於另一個任務的完成。你在定義任務時配置依賴性,從而創建復雜的任務執行順序圖。
提交到Operation Queues的任務必須是 NSOperation 對象,operation object封裝了你要執行的工作,以及所需的所有數據。由於 NSOperation 是一個抽象基類,通常你需要實現一個自定義子類來執行任務。不過Foundation framework自帶了一些具體子類,你可以創建並執行相關的任務。
Operation objects會產生key-value observing(KVO)通知,對於監控任務的進程非常有用。雖然operation queue總是並發地執行任務,你可以使用依賴,在需要時確保順序執行。
非同步設計技術
通過確保主線程自由響應用戶事件,並發可以很好地提高應用的響應性。通過將工作分配到多核,還能提高應用處理的性能。但是並發也帶來一定的額外開銷,並且使代碼更加復雜,更難編寫和調試代碼。
因此在應用設計階段,就應該考慮並發,設計應用需要執行的任務,及任務所需的數據結構。
Operation Queues
基於Objective-C,因此基於Cocoa的應用通常會使用Operation Queues
Operation Objects
operation object 是 NSOperation 類的實例,封裝了應用需要執行的任務,和執行任務所需的數據。NSOperation 本身是抽象基類,我們必須實現子類。Foundation framework提供了兩個具體子類,你可以直接使用:
類 描述
NSInvocationOperation 可以直接使用的類,基於應用的一個對象和selector來創建operation object。如果你已經有現有的方法來執行需要的任務,就可以使用這個類。
NSBlockOperation 可以直接使用的類,用來並發地執行一個或多個block對象。operation object使用「組」的語義來執行多個block對象,所有相關的block都執行完成之後,operation object才算完成。
NSOperation 基類,用來自定義子類operation object。繼承NSOperation可以完全控制operation object的實現,包括修改操作執行和狀態報告的方式。
所有operation objects都支持以下關鍵特性:
支持建立基於圖的operation objects依賴。可以阻止某個operation運行,直到它依賴的所有operation都已經完成。
支持可選的completion block,在operation的主任務完成後調用。
支持應用使用KVO通知來監控operation的執行狀態。
支持operation優先順序,從而影響相對的執行順序
支持取消,允許你中止正在執行的任務
並發 VS 非並發Operations
通常我們通過將operation添加到operation queue中來執行該操作。但是我們也可以手動調用start方法來執行一個operation對象,這樣做不保證operation會並發執行。NSOperation類對象的 isConcurrent 方法告訴你這個operation相對於調用start方法的線程,是同步還是非同步執行的。isConcurrent 方法默認返回NO,表示operation與調用線程同步執行。
如果你需要實現並發operation,也就是相對調用線程非同步執行的操作。你必須添加額外的代碼,來非同步地啟動操作。例如生成一個線程、調用非同步系統函數,以確保start方法啟動任務,並立即返回。
多數開發者從來都不需要實現並發operation對象,我們只需要將operations添加到operation queue。當你提交非並發operation到operation queue時,queue會創建線程來運行你的操作,因此也能達到非同步執行的目的。只有你不希望使用operation queue來執行operation時,才需要定義並發operations。
創建一個 NSInvocationOperation 對象
如果已經現有一個方法,需要並發地執行,就可以直接創建 NSInvocationOperation 對象,而不需要自己繼承 NSOperation。
@implementation MyCustomClass
- (NSOperation*)taskWithData:(id)data
{
NSInvocationOperation* theOp = [[[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:)
object:data] autorelease];
return theOp;
}
// This is the method that does the actual work of the task.
- (void)myTaskMethod:(id)data
{
// Perform the task.
}
@end
創建一個 NSBlockOperation 對象
NSBlockOperation 對象用於封裝一個或多個block對象,一般創建時會添加至少一個block,然後再根據需要添加更多的block。當 NSBlockOperation 對象執行時,會把所有block提交到默認優先順序的並發dispatch queue。然後 NSBlockOperation 對象等待所有block完成執行,最後標記自己已完成。因此可以使用block operation來跟蹤一組執行中的block,有點類似於thread join等待多個線程的結果。區別在於block operation本身也運行在一個單獨的線程,應用的其它線程在等待block operation完成時可以繼續工作。
NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
NSLog(@"Beginning operation.\n");
// Do some work.
}];
使用 addExecutionBlock: 可以添加更多block到這個block operation對象。如果需要順序地執行block,你必須直接提交到所需的dispatch queue。
自定義Operation對象
如果block operation和invocation operation對象不符合應用的需求,你可以直接繼承 NSOperation,並添加任何你想要的行為。
NSOperation 類提供通用的子類繼承點,而且實現了許多重要的基礎設施來處理依賴和KVO通知。繼承所需的工作量主要取決於你要實現非並發還是並發的operation。
定義非並發operation要簡單許多,只需要執行主任務,並正確地響應取消事件;NSOperation 處理了其它所有事情。對於並發operation,你必須替換某些現有的基礎設施代碼。
執行主任務
每個operation對象至少需要實現以下方法:
自定義initialization方法:初始化,將operation 對象設置為已知狀態
自定義main方法:執行你的任務
你也可以選擇性地實現以下方法:
main方法中需要調用的其它自定義方法
Accessor方法:設置和訪問operation對象的數據
dealloc方法:清理operation對象分配的所有內存
NSCoding 協議的方法:允許operation對象archive和unarchive
轉載僅供參考,版權屬於原作者。祝你愉快,滿意請採納哦
D. ios多線程中gcd的優勢及原理,線程池效率問題,何時需要取消線程任務
GCD
1.Apple提供的一套更底層、更高效的並發編程技術,純C語言、基於Block
2.支持同步或非同步任務處理,串列、並行的處理隊列,非系統調用的信號量機制,定時任務處理,進程、文件或網路的監聽任務等
優點
1.易用:GCD比之thread更簡單易用。基於block的特性導致它能極為簡單得在不同代
碼作用域之間傳遞上下文
2.效率:GCD實現功能 輕量、優雅,使得它在很多地方比之專門創建消耗資源的線程更
實用且快速
3.性能:GCD自動根據系統負載來增減線程數量,這就減少了上下文切換以及增加了計
算效率
4.安全:無需加鎖或其他同步機制
GCD內存管理
1.手動內存管理:dispatch_retain、dispatch_release
·dispatch函數名稱中含有『create』的API在不需要其生成的對象時,必須通過dispatch_release 函數進行釋放
2.ARC:iOS6之後GCD兼容ARC,不再需要用dispatch_retain或dispatch_release
E. Web 前端和 iOS 開發,你會選哪個
前端和終端作為面向用戶端的程序,有個共同特點:需要依賴用戶機器的運行環境,所以開發語言基本上是沒有選擇的,不像後台想用什麼就用什麼,iOS只能用Objective-C,前端只能javascript,當然iOS還可以用RubyMotion,前端還能用GWT/CoffieScript,但不是主流,用的人很少,真正用了也會多出很多麻煩。
這兩者有個有意思的對比:變數/方法命名的風格正好相反。蘋果一直鼓吹用戶體驗,寫代碼也不例外,程序命名都是用英文全稱並且要多詳細有多詳細,力求看變數和方法名就能知道是幹嘛的,例如application:didFinishLaunchingWithOptions:。而js因為每次都要從網路下載,要力求減少代碼體積,所以變數方法名是盡量用縮寫,實際上有代碼壓縮工具,無論變數名寫多長最終上線的效果是一樣的,但大家也都習慣了用短的命名,例如上述objc的application:didFinishLaunchingWithOptions:方法在js里習慣的命名是:$()。
objc與js都是動態語言,使用起來還蠻像,但objc是編譯型,速度快,很多錯誤也能在編譯過程中被發現,js是解釋型,性能依賴於解釋引擎,即使在強勁的v8引擎下性能也趕不上編譯型語言,語言太動態,變數完全沒有類型,寫起來爽,debug起來稍微費點勁。一直感覺js輕巧靈活放盪不羈充滿各種奇技淫巧,objc中規中矩沒c++ java那麼嚴肅也沒有js那麼靈活。
線程
前端開發幾乎不需要線程這個概念,瀏覽器實現上頁面HTML和CSS解析渲染可能與js不在同一個線程,但所有js代碼只執行在一條線程上,不會並發執行,也就不需要考慮各種並發編程的問題。在新的JS特性中可以創建worker任務,這樣的任務是可以另起一條線程並行執行的,但由於並不是所有瀏覽器都支持,不同線程傳遞數據各個標準定的還不一樣,使用場景也少,似乎沒有大規模用起來。對於資料庫操作/發送網路請求這樣的任務是在不同於js代碼執行線程的,不過這些都由瀏覽器管理,前端無需關心也無法影響這些線程,只需接收事件回調,不需要處理任何並發問題。
終端開發需要大量使用多線程,iOS有一條主線程,UI渲染都在這個線程,其他耗時長的邏輯或者資料庫IO/網路請求都需要自己另開線程執行,否則會佔用主線程的時間,導致界面無法響應用戶交互事件,或者渲染慢導致滾動卡頓。程序邏輯分布在多個線程里跑,需要處理好各種代碼並發執行可能帶來的數據不一致/時序錯亂之類的問題,並發也導致有些bug難以排查,一不留神就掉坑,需要適當用一些隊列/鎖保證程序的執行順序。iOS提供了一套多線程管理的方法GCD,已經把線程和隊列封裝得非常簡單易用功能強大,比其他端或後台是好很多了,但還是會花大量功夫在處理多線程問題上。
F. ios 怎麼應用響應式編程實現登錄
使用ReactiveCocoa實現iOS平台響應式編程
ReactiveCocoa和響應式編程
在說ReactiveCocoa之前,先要介紹一下FRP(Functional Reactive Programming,響應式編程),在維基網路中有這樣一個例子介紹:
在命令式編程環境中,a = b + c 表示將表達式的結果賦給a,而之後改變b或c的值不會影響a。但在響應式編程中,a的值會隨著b或c的更新而更新。
Excel就是響應式編程的一個例子。單元格可以包含字面值或類似」=B1+C1″的公式,而包含公式的單元格的值會依據其他單元格的值的變化而變化 。
而ReactiveCocoa簡稱RAC,就是基於響應式編程思想的Objective-C實踐,它是Github的一個開源項目,你可以在這里找到它。
關於FRP和ReactiveCocoa可以去看leezhong的這篇blog,圖文並茂,講的很好。
ReactiveCocoa框架概覽
先來看一下leezhong再博文中提到的比喻,讓你對有個ReactiveCocoa很好的理解:
可以把信號想像成水龍頭,只不過裡面不是水,而是玻璃球(value),直徑跟水管的內徑一樣,這樣就能保證玻璃球是依次排列,不會出現並排的情況(數據都是線性處理的,不會出現並發情況)。水龍頭的開關默認是關的,除非有了接收方(subscriber),才會打開。這樣只要有新的玻璃球進來,就會自動傳送給接收方。可以在水龍頭上加一個過濾嘴(filter),不符合的不讓通過,也可以加一個改動裝置,把球改變成符合自己的需求(map)。也可以把多
G. 麻煩給完整編程
print('\n'.join(input('請輸入多種水果名稱:').strip().split()))
H. 編程時選用的程序設計語言,對軟體的開發與維護的影響
【CSDN 編者按】「如果我們把人類文明想像成汽車的話,那麼軟體開發行業就相當於汽車的引擎,編程語言就像引擎的燃料。」作為一名開發者,需跟隨技術潮流的發展來學習新技術。2020年,你有計劃新學一門編程語言嗎?
本文作者從一名架構師的角度,詳細分析了7種現代編程語言的優點與功能,你對哪門語言最感興趣呢?
作者 | Md Kamaruzzaman,軟體架構師
譯者 | 彎月,責編 | 伍杏玲
封圖| CSDN 下載於視覺中國
出品 | CSDN(ID:CSDNnews)
以下為譯文:
如果我們把人類文明想像成汽車的話,那麼軟體開發行業就相當於汽車的引擎,而編程語言就像引擎的燃料。作為一名開發者,今年你應該學習哪種編程語言呢?
學習一種新的編程語言無疑是時間、精力和智力上的巨大投資, 但是學習一種新的編程語言可以提升你的軟體開發技術力,促進你的職業發展。
在這里,我將獻上一份現代編程語言的列表,這些語言不僅有助於提高你的生產力,而且還可以促進你的職業發展,並讓你成長為更優秀的開發人員。這份列表還涵蓋了非常廣泛的領域:系統編程、應用程序開發、Web開發、科學計算等。
什麼是現代編程語言?
「現代編程語言」這個說法本身就很含糊。許多人認為Python和JavaScript等語言是現代編程語言,還認為Java是一種古老的編程語言。實際上,這幾種語言大約在同一時間出現:1995年。
大多數主流編程語言是上個世紀開發的:七十年代(如C)、八十年代(如C ++)、九十年代(如Java、Python、JavaScript)。這些語言在設計上並沒有考慮現代軟體開發生態系統:多核CPU、GPU、快速的互聯網、移動設備、容器和雲等。盡管許多語言中的許多功能都已進行一些改進,如並發等,而且在不斷調整自己以適應時代,但它們依然保留了向後兼容性,無法拋棄那些過時的舊功能。
在這方面,Python就做得很好(某種意義上也未必是好事),Python 2和Python 3兩者之間有明確的分界線。很多語言常常會為解決同一個問題提供十餘種的方法,同時又沒有顧及到開發人員的感受。根據StackOverflow的開發人員調查,大多數舊時的主流編程語言在「最可怕的語言」排名都名列前茅:
如果非要在新舊編程語言之間劃個界限的話,那麼應該是2007年6月29日,也就是第一台iPhone發行的時候。在這之後,編程語言界發生了很大變化。因此,在本文的列表中,我只考慮2007年以後的編程語言。
為什麼要學習新語言?
首先,現代編程語言充分利用現代計算機硬體(多核CPU、GPU、TPU)、移動設備、大量數據、高速互聯網、容器和雲的優勢。大多數現代編程語言會關注開發人員的體驗,比如:
簡潔明了的代碼(減少樣板代碼)
內置的並發支持
空指針安全
類型推斷
簡潔的功能集
降低學習難度
融合所有編程範例的最佳功能
本文列表的許多編程語言都帶有革命性地變化,並將永久地改變軟體行業。一些已成為主流編程語言,還有一些則有望取得突破。因此選擇這些語言作為第二種編程語言是明智的做法。
Rust
一直以來,系統編程語言環境主要由靠近硬體的語言(如C、C ++等)主導。盡管它們可以完全控製程序和硬體,但是它們缺乏內存安全性。即使它們支持並發,使用C/C ++編寫並發程序也很困難,因為沒有並發安全性。還有一些流行的編程語言是解釋性語言,例如Java、Python、Haskell。這些語言具備安全性,但需要龐大的運行時或虛擬機。由於它們的運行時間長,因此Java等語言不適合於系統編程。
許多人曾嘗試將C/C ++的功能與Java、Haskell的安全性相結合。然而,Rust才是第一個成功實現了這一點的編程語言。
Graydon Hoare在業余項目中開發出了Rust,他的靈感來自研究編程語言Cyclone。Rust是開源的,由Mozilla與許多其他公司和社區一起領導這門語言的開發。Rust於2015年首次發布,並很快引起了社區的關注。
主要特徵:
通過所有權和借用概念提供內存安全和並發安全。
內存安全和並發安全在編譯時確保,即如果程序代碼可以編譯,那麼內存既安全又沒有數據競爭。這是Rust最吸引人的功能。
它還提供了Haskell中元編程的表現力。憑借不可變的數據結構和功能編程功能,Rust提供了功能並發和數據並發。
Rust的速度非常快,純Rust的性能甚至優於純C。
在沒有運行時的情況下,Rust可以完全控制現代硬體(TPU、GPU、多核CPU)。
Rust具有LLVM支持。因此,Rust提供一流的與WebAssembly的互操作性,而且Web代碼也非常快。
流行度:
自2015年首次亮相以來,Rust已被開發人員廣泛接受,並在StackOverflow開發人員調查中連續四年(2016、2017、2018、2019)被評選為最受歡迎的語言:
根據GitHub Octoverse的調查,Rust是運行速度第二快的語言,僅次於Dart:
此外,根據編程語言流行度排名網站PyPl的數據,Rust排名第18位,並呈上升趨勢:
對比Rust提供的功能集,我們就會明白為什麼微軟、亞馬遜、Google等科技巨頭相繼宣布投資Rust作為一種長期的系統編程語言。
根據Google統計的趨勢,在過去的5年中,Rust的熱度每年都在增加。
主要用途:
系統編程
Serverless 計算
商業應用
主要競爭對手:
C
C++
Go
Swift
Go
在本世紀初,Google面臨兩個擴展問題:開發擴展和應用程序擴展。開發擴展問題指的是他們不能僅通過投入開發人員的方式來添加更多功能。應用程序擴展問題則指他們無法開發出一款能夠擴展到Google級別的計算機集群的應用程序。
所以在2007年左右,Google創建了一種新的編程語言,用於解決這兩個擴展問題。兩位才華橫溢的Google軟體工程師Rob Pike(UTF-8)和Ken Thompson(UNIX OS)創建了一種新語言。
2012年,Google正式發布了第一版的Go編程語言。Go是一種系統編程語言,但與Rust不同,它還具有Runtime和垃圾收集器(幾兆位元組)。但是與Java或Python不同,這個Runtime包含了生成的代碼。最後,Go生成了一個本地的二進制代碼,可以在沒有附加依賴項或運行時的情況下在計算機中運行。
主要特徵:
Go具有一流的並發支持。Go不通過線程和鎖提供「共享內存」並發性,因為編程難度太大。相反,它提供了基於CSP的消息傳遞並發性(基於Tony Hoare的論文)。Go使用「 Goroutine」(輕量級綠色線程)和「 Channel」進行消息傳遞。
Go最大的殺手級功能是:簡單,它是最簡單的系統編程語言。新手軟體開發人員只需幾天就可以編寫高效的代碼,就像Python一樣。有些大規模的雲原生項目(如Kubernetes、Docker)都是用Go編寫的。
Go還內置了垃圾收集器,這意味著開發人員無需擔心C/C++中的內存管理問題。
Google投入了大量資金打造Go。因此Go擁有大量的工具支持。新手Go開發人員擁有大量的工具生態系統。
一般,開發人員80%的時間都花在了維護現有代碼上,用於編寫新代碼的時間只佔20%。由於其簡單性,Go在語言維護方面表現出色。如今,Go在業務應用程序中大量使用。
流行度:
Go一問世就受到了軟體開發社區熱烈的歡迎。2009年-2018年,Go一直在TIOBE編程語言排行榜上徘徊。Go的成功為Rust等新一代編程語言鋪平了道路。
如今,Go已是主流編程語言。最近,Go團隊宣布了有關「Go 2」的消息,這門編程語言的發展會更加穩固。
幾乎在所有的流行編程語言排行榜中,Go的排名都很高,已超過許多現有的語言。自2019年12月以來,在TIOBE指數排名中,Go名列第15位:
根據StackOverFlow的調查,十大最受喜愛的編程語言中,Go也位列其中:
此外,根據GitHub的數據,Go也是十大發展最迅速的語言之一:
Google趨勢顯示,在過去的5年中,Go的熱度每年都在增加。
主要用途:
系統編程
Serverless 計算
商業應用
雲原生開發
主要競爭對手:
C
C++
Rust
Python
Java
Kotlin
Java 是企業軟體開發領域無可爭議的王者。近年來,Java受到了一些負面評論:過於冗長,大量樣板代碼,容易出現意外的復雜性。但是,關於Java虛擬機(JVM)的爭論卻很少。JVM是軟體工程的傑作,經過了時間的考驗,提供了硬核的runtime。
多年來,Scala等JVM語言一直在努力克服Java的缺點,想成為更好的Java,但他們都失敗了。最終,這場提升Java的探索以Kotlin的誕生結束。Jet Brains(流行的IDE IntelliJ背後的公司)開發了Kotlin,它可以在JVM上運行,克服了Java的很多缺點,提供許多現代功能。
與Scala不同的是,Kotlin比Java更簡單,還可在JVM中提供與Go或Python開發人員同等的生產力。
Google宣布Kotlin是一流的Android應用開發語言,因此Kotlin在社區中的接受度得到了大幅提高。自2017年以來,同樣受歡迎的Java Enterprise框架Spring也開始支持Kotlin。我曾嘗試結合Kotlin與Reactive Spring使用,體驗非常棒。
主要特徵:
Kotlin的主要賣點在於其語言設計。我總是將Kotlin視為JVM上的Go/Python,因為它簡潔明了的代碼。因此,Kotlin的生產力很高。
與許多其他現代語言一樣,Kotlin提供了Null指針、安全性、類型推斷等功能。
由於Kotlin也運行在JVM中,因此現有Java庫龐大的生態系統都可供使用。
Kotlin是一流的Android應用開發語言,並且已經超過Java,成為開發Android應用的首選。
Kotlin得到了JetBrains和Open Source的支持,因此具有出色的工具支持。
Kotlin有兩個有趣的項目:Kotlin Native(將Kotlin編譯為原生代碼)和kotlin.js(Kotlin到JavaScript)。如果成功,則可以在JVM外部使用Kotlin。
Kotlin還提供了一種簡單的方式來編寫DSL(域特定語言)。
流行度:
自2015年首次發布以來,Kotlin的知名度不斷飆升。根據Stack Overflow,Kotlin是2019年第四大最受歡迎的編程語言:
Kotlin還是增長最快的編程語言之一,排名第四:
在流行編程語言排名網站PyPl的排名中,Kotlin名列第十二名,並具有較高的上升趨勢:
自從Google宣布Kotlin是一流的Android應用開發語言以來,Kotlin的流行趨勢出現了大幅上漲,如下所示:
主要用途:
企業應用程序
主要競爭對手:
TypeScript
JavaScript是一門優秀的編程語言,在2015年之前,JavaScript有很多缺點。著名的軟體工程師Douglas Crockford寫了一本書名為《JavaScript: The Good Parts》,暗示了JavaScript有很糟的部分。無模塊化,還有「回調地獄」,因此開發人員都不喜歡維護特別大的JavaScript項目。
Google甚至還開發了一個平台,可將Java代碼反編譯為JavaScript代碼(GWT)。許多公司和個人都曾嘗試開發更好的JavaScript,例如CoffeeScript、Flow、ClojureScript。最終,微軟的TypeScript取得了成功。
微軟的一隊工程師在著名的Anders Hejlsberg的帶領下,創建了JavaScript的靜態類型、模塊化超集——TypeScript。
TypeScript可以編譯為JavaScript。於2014年首次發布後,TypeScript很快引起了社區的關注。Google當時還計劃開發JavaScript的靜態類型超集。Google對TypeScript青睞有加,以至於他們沒有開發新的語言,而是選擇與微軟合作改進TypeScript。
Google選擇TypeScript作為其SPA框架Angular 2+的主要編程語言。此外,流行的SPA框架React也提供對TypeScript的支持。另一個流行的JavaScript框架Vue.js也宣布將使用TypeScript開發新的Vue.js 3:
另外,node.js的創建者Ryan Dahl已決定使用TypeScript來開發安全的Node.js替代品Deno。
主要特徵:
流行度:
開發人員喜歡TypeScript的優雅語言設計。在StackOverFlow最受歡迎的語言類別的調查中,TypeScript與Python並列第二名:
根據GitHub的排名,TypeScript是增長最快的編程語言之一,排名第五:
從GitHub的貢獻度來看,TypeScript排名第七,打進了前十:
Google的趨勢表明,在過去的幾年中,TypeScript的熱度越來越高:
主要用途:
主要競爭對手:
Swift
當初喬布斯拒絕在iOS中支持Java(和JVM),他認為Java不再是主流編程語言。如今我們發現喬布斯當初的估計是錯的,雖然iOS仍然不支持Java。蘋果選擇了Objective-C作為iOS中的首選編程語言。Objective-C是一門很難掌握的語言,它不支持現代編程語言所要求的高生產力。
後來,蘋果的Chris Lattner和其他人開發了一種多範例、通用的、編譯編程語言——Swift,來替代Objective-C。Swift的第一個穩定版本於2014年發布。Swift還支持LLVM編譯器工具鏈(也由Chris Lattner開發)。Swift與Objective-C代碼庫具有出色的互操作性,並且已確立為iOS應用開發中的主要編程語言。
主要特徵:
流行度:
開發人員對Swift的喜愛不亞於許多其他現代編程語言。根據StackOverflow的調查,Swift在最受歡迎的編程語言中排名第六:
2019年,在TIOBE的編程語言排名中,Swift的排名上升到了第10名。鑒於這種編程語言只有5年的歷史,可以說是成績斐然:
Google的趨勢表明,在過去的幾年中,Swift的熱度出現了激增:
主要用途:
主要競爭對手:
Dart
Dart是Google出品的第二大編程語言。Google是Web和Android領域的巨頭,因此Google在Web和應用領域開發自己的編程語言也不足為奇。在丹麥軟體工程師Lars Bak(領導Chrome的 JavaScript V8引擎開發)的帶領下,Google於2013年發布了Dart。
Dart是一種通用編程語言,支持「強類型」和「面向對象」編程。Dart也可以轉編譯為JavaScript,凡是JavaScript可以運行的任何地方(例如Web、移動、伺服器)幾乎都可以運行 Dart。
主要特徵:
流行度:
根據GitHub Octoverse數據顯示,Dart是2019年增長最快的編程語言,去年它的流行度增長了五倍:
根據TIOBE指數顯示,Dart排名第23,僅用了4年時間就超過了很多其他的現代編程語言:
根據StackOverflow的調查,Dart在最受歡迎的編程語言中排名第12:
受Flutter的影響,Google的趨勢表明,在過去的兩年中,Dart的熱度急劇上升:
主要用途:
主要競爭對手:
Julia
本文提及的大多數編程語言都是由大型公司開發的,但Julia是個例外。科技計算領域通常都會使用動態語言,例如Python、Matlab。雖然這些語言提供易於使用的語法,但不適用於大規模的科技計算。他們需要使用C/C ++庫執行CPU密集型任務,因此這就產生了著名的「兩種語言」的問題,因為他們需要粘合代碼來綁定兩種語言。由於編寫的代碼需要在兩種語言之間來回切換,因此總是會損失部分性能。
為了解決這個問題,麻省理工學院的一隊研究人員計劃從頭開始創建一種新的語言,這種語言既可以利用現代硬體的優勢,而且還結合其他語言的優勢。於是,Julia誕生了。
Julia是一種動態的高級編程語言,提供一流的並發、並行和分布式計算支持。Julia的第一個穩定版本於2018年發布,並很快受到社區和行業的關注。Julia可用於科學計算、人工智慧和許多其他領域,而且還可以解決「兩種語言」的問題。
主要特徵:
流行度:
Julia在許多領域主要與Python競爭。由於Python是最流行的編程語言之一,因此Julia想晉升主流還需要幾年的時間。
雖然Julia非常新(只有一歲),但仍在TIOBE指數中排到第43名:
Google趨勢顯示,在過去的一年中,Julia的熱度在穩步增長:
但是考慮到Julia的功能集,以及NSF、DARPA、NASA、因特爾等公司的推動,相信Julia取得突破的進展只是時間的問題。
主要用途:
主要競爭對手:
原文鏈接:https://towardsdatascience.com/top-7-modern-programming-language-to-learn-now-156863bd1eec
本文為 CSDN 翻譯,轉載請註明來源出處。
【End】
Python
Matlab
科學計算
高性能計算
數據科學
可視化
與Rust一樣,Julia的主要特徵在於語言的設計。這種語言在不犧牲性能的情況下,將高性能和科學計算中現有編程語言的一些功能結合在一起。就目前的情況來看,Julia出色地完成了這項任務。
Julia是一種動態編程語言,支持類型系統但類型不是必須的。因此,Julia這種編程語言很容易學習,生產力很高。
Julia的核心是多調度編程範例。
Julia內部支持並發、並行和分布式計算。
Julia為I/O密集型任務提供非同步I/O。
Julia的運行速度非常快,可用於需要數百萬個線程的科學計算。
JavaScript
TypeScript
應用開發
UI開發
與Go一樣,Dart也非常注重開發人員的工作效率。由於Dart簡潔的語法,以及高效的生產力,受到開發人員的喜愛。
Dart還提供「強類型」和「面向對象」編程。
Dart是少數同時支持JIT編譯(運行時編譯)和AOT編譯(創建時編譯)的編程語言之一。因此,Dart可以針對JavaScript運行時(V8引擎),並且Dart可以編譯為快速的原生代碼(AOT編譯)。
跨平台原生應用程序開發平台Flutter選擇了Dart作為開發iOS和Android應用的編程語言。從那以後,Dart的流行度越來越高。
與Goog的Go編程語言一樣,Dart也具有出色的工具支持和龐大的Flutter生態系統。Flutter的日益普及也會推動Dart的採用率升高。
Objective-C
Rust
Go
iOS應用開發
系統編程
客戶端開發(通過WebAssembly)
Swift的殺手級功能之一是其語言設計。語言本身很簡單,語法簡潔,比Objective-C更高效。
Swift還提供了現代程序語言的功能:null安全。此外,它還提供了語法糖來避免「厄運金字塔」。
作為一種編譯語言,Swift和C++一樣快。
Swift支持LLVM編譯器工具鏈。因此,我們可以在伺服器端編程,甚至瀏覽器編程(使用WebAssembly)中使用Swift。
Swift提供了自動引用計數(ARC)支持,可抑制內存管理的不善。
JavaScript
Dart
Web UI開發
伺服器端開發
與Go或Kotlin同樣,TypeScript的主要特徵也是語言設計。TypeScript憑借其簡潔明快的代碼,成為了目前最優雅的編程語言之一。就開發人員的生產力而言,它與JVM或Go/Python上的Kotlin並駕齊驅。TypeScript是生產力最高的JavaScript超集。
TypeScript是JavaScript的強類型超集,特別適合大型項目,而且可以稱為「可擴展的JavaScript」。
單頁應用程序框架的「三巨頭」(Angular、React、Vue.js)為TypeScript提供了出色的支持。在Angular中,TypeScript是首選的編程語言。在React和Vue.js中,TypeScript越來越受歡迎。
最大的兩家技術巨頭:微軟和Google正在合作開發由活躍的開源社區支持的TypeScript。因此,TypeScript擁有最好的工具支持。
由於TypeScript是JavaScript的超集,因此凡是可以運行JavaScript的任何地方都可以運行TypeScript,包括瀏覽器、伺服器、移動設備、物聯網設備和雲。
Java
Scala
Python
Go
I. 請問現在從零開始學習iOS開發,學習Objective-C語言還是學習Swift語言
沒基礎從C學起,C不需要深入,搞懂指針(指向函數/結構體/數組的指針),搞懂結構體就基本OK了。
有基礎直接進入OC,C++可用無視(以後做游戲用cocos2dx框架才考慮吧)。別聽一樓這逗比的回答,他根本什麼都不懂.....可能根本就不會編程。就來這里瞎說的。
雖然上年推出了swift,但是你知道現在的SDK基本上都是用OC來寫的嗎?80%的API介面都是用OC來寫的,現在的蘋果本質上只是幫你封裝好了,底層幫你裝換成OC。(需要給蘋果一點時間來完善SDK,或許1、2年吧)還有更底層的,例如GCD(並發編程方面),CG框架(繪圖用的)。等等等等。。。。。都是赤裸裸的C語言。沒有OOP的概念。你說你需要有C和OC的基礎嗎?
還有現在的公司,特別是大公司,基本上的項目都是OC寫的,你不會OC?你怎麼讀懂代碼?怎麼重構代碼?不要說OC,很多公司的老項目,連SB和NIB都沒有(一是當時沒有SB,而是當時用SB不方便源代碼管理,這個等到你有開發經驗了才會理解...),都是100%純手寫代碼的。除非開啟一些新項目才會有IB。不要說看不懂OC,你連面試關都過關了,因為單單OC這個知識點就考死你了。
所以說基礎一定要扎實。還是一步一步來吧,最後告訴你,你有基礎的話,swift根本不用學,我當時用了1天看文檔,就徹底搞懂swift了....
J. ios數據載入完會調用哪個方法
1.下面來看下如何使用gcd編程的非同步
Objective-c代碼
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 處理耗時操作的代碼塊...
//通知主線程刷新
dispatch_async(dispatch_get_main_queue(), ^{
//回調或者說是通知主線程刷新,
});
});
復制代碼
dispatch_async開啟一個非同步操作,第一個參數是指定一個gcd隊列,第二個參數是分配一個處理事物的程序塊到該隊列。
dispatch_get_global_queue(0, 0),指用了全局隊列。
一般來說系統本身會有3個隊列。
global_queue,current_queue,以及main_queue.
獲取一個全局隊列是接受兩個參數,第一個是我分配的事物處理程序塊隊列優先順序。分高低和默認,0為默認2為高,-2為低
Objective-c代碼
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
復制代碼
處理完事物後,需要將結果返回給或者是刷新UI主線程,同樣,和上面一樣,抓取主線程,程序塊操作。
//天啊,手賤不小心點到了home間,會退後發現沒保存~~~寫的並發一塊內容都沒了!!!
二:GCD之並發概念
其實對於編程中,我們一直提及到的幾個概念,同步,非同步,並發,鎖等。
有時覺得一下子還真說不清。
下面我們以上面提到的圖片載入來看下這3個概念我的理解
1同步:
Objective-c代碼
for (int i = 0 ; i < 10; i++) {
UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
[myImgV[i] setImage:img];
}
復制代碼
假設我要載入10個圖片,我現在擁有這些圖片的資源地址,保存在一個數組中。
我們先以獲取第一張圖片來舉例:
同步執行的概念就是,我獲取完第一張圖片的,
執行了for循環第一句返回了img後,我才能執行第二句,UI界面的刷新。
如果第一句返回的時間需要10秒,那我程序的響應就彷彿一直卡在這里一樣,我無法進行其他操作。必須等它返回!!
因此,同步的一個很好理解的感念就是,一步走到黑。
2.非同步
for (int i = 0 ; i < 10; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 處理耗時操作的代碼塊...
UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
//通知主線程刷新
dispatch_async(dispatch_get_main_queue(), ^{
//回調或者說是通知主線程刷新,
[myImgV[i] setImage:img];
});
});
復制代碼
看了這代碼,我們會說,非同步操作那個假設還是要10秒啊,總體看來,執行一張圖片的時間載入還是要在10秒左右啊,
貌似非同步沒什麼鳥用么。但是,別忽略了其中一點,也黑絲核心的一點,此時我們圖片獲取操作放在里一個線程隊列里,
此刻,雖然我們看著圖片的載入還是需要10秒才會出來,但是,在這10秒期間,我們的UI主線程是可以操作的,比如界面上有個按鈕,你是可以按的
而不是如上面的同步,在10面期間,我是只能乾等著,什麼都做不了。
非同步的核心概念就是一個新線程,一個消息回調通知。
3.並行
我們還是以上代碼為例。前面我強調了,我們只看一張圖片的載入,現在,回到我們第一眼看到代碼的思維上去,
一個for循環。其實上面代碼過後,我是創建了10個非同步線程。
好吧,到此,我們應該明白這三個概念了。
同步,其實我前面的例子舉得有些局限,就是這個例子本身就說明不需要同步執行,然後給大家大感覺是
同步是編程中一個忌諱點一樣,其實不然,很多時候。我們真是需要同步來做一些限制(比如線程中提出的同步鎖?聽著就感覺有用么
雖然可能並不如我們想的那樣的運用同步,但是至少說明這個概念同樣是有用的)
我還是以剛才那個載入圖片為例子,來個簡單的說明如何運用同步的好處。
當然,我只是模擬一個同步的情況。
假設我們現在圖片的載入是這樣的,圖片本身為在載入前是一個默認的圖片,上面寫著,點擊我載入,點擊後會調用網路載入方法,然後圖片顯示載入中,
然後我們雙擊圖片時(當然,理論上是在載入完後)讀取圖片網路圖片放大,好吧,到這里應該能想到要表達的情況了。
整個流程應該是點擊圖片->載入->雙擊查看。那如果成了點擊->載入中(以返回了圖片的作者和信息)-》雙擊圖片(通過前面請求返回的大圖鏈接顯示大圖)-》
完全載入返回(返回了大圖鏈接)。此時我們看不到圖像的大圖了。因為我們操作在返回前了,也就是說,
很多時候,我們下一個動作的操作必須需要用到前面一個操作的數據時,我們會給他做認為的同步編程,比如加個按鈕鎖。
這是我們又會疑惑道,下一個執行需要用到前一個執行的,那第一個例子中的for循環的第二句不是要用到么,這么說
他們必須要同步啊,如果你這么想了,好巧,我們想到一塊去了~
但是,注意,前面我們到的非同步是為了解決我點擊其他按鈕的操作,而不是說更新UI操作。下載和更新UI操作在我們看來必須是同步的
這是對的,但是那種做導致了系統本身一些監聽事件監聽到點擊處理在那個請求之後了,這邊的載入圖片其實要看成一次事件執行,
因為對於事件的這一抽象單元,其實是一種可人為定義的寬廣度。
也就是說,一次數據獲取和圖像填充,其實算是一個圖像獲取載入事件,事件可以說包含兩個單元,載入和填充。
而整個這個事件對於我們點擊其他按鈕並無關系,那麼也就說明了無需同步。
有道理啊,但是若果我們要點擊這個圖片呢,也就是回到剛才那個可以雙擊的假設。
此處也許我么又忽略了一點為什麼載入中我們能點擊雙擊呢,也就這樣的假設是獲取圖片已經做了非同步,但是我們下一步操作又是需要同步的
因此做了人為的同步鎖定。
好了,說的太多了,當時至少我們明白兩點
非同步可能是為了反正耗時操作造成的主線程堵塞,
同步是為了解決一些不必要錯誤和麻煩。也許到這里,我們腦中會聯想到的所謂的線程安全性。
其實同步以及同步鎖,卻是應該是考慮到這樣的不必要和不安全因素。
最後在簡單闡述下非同步和並發關系。
其實看了上面說的,非同步只是提供了一種多線程處理的概念,
並發是更像是非同步的一種大規模實現。
就好比說,非同步提出了可以用小弟去收保護費,收完了告訴並交給自己,而我在期間做其他要做的事。
並發突然想到,非同步這個很有道理啊,那我有4個地方要收,一個小弟去收,雖然我還是可以閑著做其他的事,
但是小弟跑四個地方,我拿到錢所需要的時間還是和我自己去收一樣的,只不過我不用那麼費勁了,還能做其他事了。
因此,並發覺得應該派四個小弟去,因為每個場地的保護費各不相乾的。(剛看了個紐約黑幫~)。
因此說,非同步解決了線程堵塞,而並發則是在非同步的基礎上,提高了符合特性事件的處理時間效率。
當然,如果10個圖片本身相互間是沒什麼聯系,但是,最後一個事件需要處理計算這10個圖片的總容量值。
那麼可以用 dispatch_group_async。
具體就看文檔吧。
總體來說,看了iosGCD這塊,一是讓我熟悉了block編程特性,還有是熟悉如何使用ios提供的GCD特性
來完成多線程編程。