十年專注于品牌網(wǎng)站建設(shè) 十余年專注于網(wǎng)站建設(shè)_小程序開發(fā)_APP開發(fā),低調(diào)、敢創(chuàng)新、有情懷!
      南昌百恒網(wǎng)絡(luò)微信公眾號 掃一掃關(guān)注
      小程序
      tel-icon全國服務(wù)熱線:400-680-9298,0791-88117053
      掃一掃關(guān)注百恒網(wǎng)絡(luò)微信公眾號
      掃一掃打開百恒網(wǎng)絡(luò)微信小程序

      百恒網(wǎng)絡(luò)

      南昌百恒網(wǎng)絡(luò)

      如何進(jìn)行程序性能優(yōu)化(三)

      百恒網(wǎng)絡(luò) 2017-05-20 5213

      1.可重用對象的使用

      在iOS的一些視圖中,它們的內(nèi)部包含了子視圖,當(dāng)父視圖顯示區(qū)域發(fā)生變化時(shí)(如用手滑動(dòng)屏幕),原來在屏幕中的子視圖就會(huì)滑出到屏幕之外,而原來在屏幕之外的子視圖就有機(jī)會(huì)進(jìn)入屏幕中。如圖1所示,當(dāng)屏幕向上滑動(dòng)時(shí),Cupertino單元格滑出屏幕之外,Sherman Oaks單元格滑入到屏幕中。

      表視圖中的可重用單元格

      圖1 表視圖中的可重用單元格

      這些操作會(huì)有什么問題嗎?南昌網(wǎng)絡(luò)公司小編告訴你如果每次新單元格進(jìn)入到屏幕中都去實(shí)例化一個(gè)新的單元格,必然增加內(nèi)存開銷。采用可重用對象設(shè)計(jì)可以不去實(shí)例化新的單元格,而是先使用可重用單元格標(biāo)識(shí)到視圖中去找,如果找到則使用,沒有則創(chuàng)建。

      在iOS 6之后,可以使用可重用對象的父視圖有表視圖、集合視圖(UICollectionView)和地圖視圖(MKMapView)。

      1.1 表視圖中的可重用對象

      在iOS 6之后,表視圖中有兩種子視圖采用可重用對象設(shè)計(jì),它們是表視圖單元格(UITableViewCell)和表視圖節(jié)頭節(jié)腳(UITableViewHeaderFooterView)。

      (1)表視圖單元格

      表視圖單元格的重用方法有兩個(gè):dequeueReusableCellWithIdentifier:方法和 dequeueReusableCellWithIdentifier:forIndexPath:方法。

      通過dequeueReusableCellWithIdentifier:方法,可以用標(biāo)識(shí)符從表視圖中獲得可重用單元格,模式代碼如下:

      通過dequeueReusableCellWithIdentifier:方法,可以用標(biāo)識(shí)符從表視圖中獲得可重用單元格,模式代碼

      要在表視圖數(shù)據(jù)源的tableView:cellForRowAtIndexPath:方法中使用可重用單元格設(shè)計(jì),首先通過dequeueReusableCellWithIdentifier:方法從表視圖中找,如果cell為空,則需要使用initWithStyle:reuseIdentifier:構(gòu)造器創(chuàng)建。

      dequeueReusableCellWithIdentifier:forIndexPath:方法是iOS 6之后提供的方法。與上一個(gè)方法相比,該方法的簽名多了forIndexPath:部分。它可以通過指定單元格位置獲得可重用單元格,不需要判斷,模式代碼如下:

      dequeueReusableCellWithIdentifier:forIndexPath

      這個(gè)方法的使用有一些限制,它只能應(yīng)用于iOS故事板中,并且在故事板中設(shè)計(jì)表視圖單元格后,指定表視圖單元格為動(dòng)態(tài)的,Identifier屬性設(shè)置為cellIdentifier。圖2設(shè)定了表視圖單元格的屬性。

      設(shè)定表視圖單元格的屬性

      圖2 設(shè)定表視圖單元格的屬性

      (2)UITableViewHeaderFooterView也是iOS 6之后新加的內(nèi)容,節(jié)頭和節(jié)腳也會(huì)反復(fù)出現(xiàn),它也需要可重用設(shè)計(jì)。使用表視圖的dequeueReusableHeaderFooterViewWithIdentifier:方法獲得UITableViewHeaderFooterView對象后,如果沒有可重用的UITableViewHeaderFooterView對象,則使用initWithReuseIdentifier:構(gòu)造器創(chuàng)建。其模式代碼如下:

      UITableViewHeaderFooterView

      需要在表視圖委托協(xié)議UITableViewDelegate中的tableView:viewForHeaderInSection:方法中使用可重用對象設(shè)計(jì)。

      1.2 集合視圖中的可重用對象

      集合視圖在iOS 6之后才可以使用。它也有兩種子視圖采用可重用對象設(shè)計(jì),它們是單元格視圖和補(bǔ)充視圖,這兩個(gè)視圖都繼承自UICollectionReusableView,使用時(shí)需要自己編寫相關(guān)代碼。

      (1)單元格視圖

      在集合視圖中,我們可以使用UICollectionView的dequeueReusableCellWithReuseIdentifier:forIndexPath:方法獲得可重用的單元格,模式代碼如下:

      使用UICollectionView的dequeueReusableCellWithReuseIdentifier:forIndexPath:方法獲得可重用的單元格,模式代碼

      在上述代碼中,collectionView:cellForItemAtIndexPath:方法是集合視圖的數(shù)據(jù)源方法,其中Cell是我們自定義的繼承自UICollectionReusableView的單元格類。使用dequeueReusableCellWithReuseIdentifier:時(shí),需要使用故事板設(shè)計(jì)UI,并且需要將單元格的Identifier屬性設(shè)置為Cell(如圖3所示)。

      設(shè)定集合視圖單元格的屬性

      圖3 設(shè)定集合視圖單元格的屬性

      (2)補(bǔ)充視圖

      集合視圖單元格可以使用UICollectionView的dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:方法獲得可重用的補(bǔ)充視圖,模式代碼如下:

      使用UICollectionView的dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:方法獲得可重用的補(bǔ)充視圖,模式代碼

      collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法是集合視圖的數(shù)據(jù)源方法,其中HeaderView是我們自定義的繼承自UICollectionReusableView的補(bǔ)充視圖類。使用dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:時(shí),需要使用故事板設(shè)計(jì)UI,并將補(bǔ)充視圖的Identifier屬性設(shè)置為HeaderIdentifier,如圖4所示。

      設(shè)定補(bǔ)充視圖的屬性

      圖4 設(shè)定補(bǔ)充視圖的屬性

      1.3 地圖視圖中的可重用對象

      在開發(fā)地圖應(yīng)用時(shí),也有一個(gè)可重用對MKPinAnnotationView,它是在地圖上的一個(gè)標(biāo)注。使用地圖視圖的

      dequeueReusableAnnotationViewWithIdentifier:方法,可以獲得MKPinAnnotationView對象。如果沒有可重用的MKPinAnnotationView對象,則使用initWithAnnotation:reuseIdentifier:構(gòu)造器創(chuàng)建。其模式代碼如下:

      dequeueReusableAnnotationViewWithIdentifier

      initWithAnnotation:reuseIdentifier:構(gòu)造器

      這段處理代碼是地圖視圖中常用的處理方式,請大家牢記。

      2.并發(fā)處理與多核 CPU

      并發(fā)處理能夠同時(shí)處理多個(gè)任務(wù)。在CPU單核時(shí)代,可以使用多線程技術(shù)進(jìn)行并發(fā)處理。現(xiàn)在,iOS設(shè)備的CPU已經(jīng)進(jìn)入多核時(shí)代,從iPhone 4S和iPad 2之后開始采用A5雙核CPU設(shè)計(jì)。異步設(shè)計(jì)方法可以充分地發(fā)揮多核優(yōu)勢。GCD(Grand Central Dispatch)是一種異步方法,是專為多核CPU而設(shè)計(jì)的并發(fā)處理技術(shù)。

      本節(jié)中,南昌網(wǎng)絡(luò)公司小編就和大家一起來學(xué)習(xí)主線程阻塞問題以及GCD的相關(guān)內(nèi)容。

      2.1 主線程阻塞問題

      主線程所做的事情應(yīng)該是響應(yīng)用戶輸入、事件處理、更新UI,而耗時(shí)的任務(wù)不要在主線程中處理。由于耗時(shí)任務(wù)使得主線程被阻塞了,不能響應(yīng)用戶的請求,這樣應(yīng)用的用戶體驗(yàn)會(huì)很差。

      下面我們先看一個(gè)例子。如圖5所示,點(diǎn)擊Load Image按鈕,會(huì)從http://www.51work6.com/book/test2.jpg中加載圖片。當(dāng)我們點(diǎn)擊Load Image按鈕時(shí),按鈕會(huì)一直處于按下狀態(tài)而不彈起,直到圖片顯示“完成”。這是因?yàn)橹骶€程要進(jìn)行耗時(shí)的處理(如進(jìn)行網(wǎng)絡(luò)通信、數(shù)據(jù)傳輸?shù)热蝿?wù)),導(dǎo)致主線程不能響應(yīng)用戶的輸入和請求,這就是我們要討論的線程阻塞問題。

      主線程阻塞案例

      圖5 主線程阻塞案例

      下面我們看看代碼部分。在BlockDemo工程中,ViewController中click:方法的代碼如下:

      ViewController中click:方法的代碼

      由于不能直接通過URL創(chuàng)建UIImage對象,因此先構(gòu)建NSData對象,它是從URL請求回來的二進(jìn)制數(shù)據(jù)對象,然后再用它來構(gòu)建UIImage對象。最后,把UIImage對象賦值給UIImageView的image屬性。

      那么,如何解決主線程阻塞問題呢?那就是把這些執(zhí)行比較耗時(shí)的阻塞線程的任務(wù)從主線程中移出到其他線程中處理。

      2.2 選擇 NSThread 還是 GCD

      解決主線程阻塞問題時(shí),我們可以使用多線程。NSThread是多線程類,但是麻煩的是我們需要管理線程,包括創(chuàng)建線程、線程間通信和銷毀線程等。

      GCD(Grand Central Dispatch)是基于C語句級別的API,它提供了C函數(shù)。GCD代碼編寫簡單,還支持多核CPU處理。GCD是蘋果重點(diǎn)推薦的并發(fā)技術(shù),唯一的缺陷是它是基于C語言的API。

      在GCD中,有一個(gè)重要的概念,那就是派發(fā)隊(duì)列(dispatch queue)。派發(fā)隊(duì)列是一個(gè)對象,它可以接受任務(wù),并將任務(wù)以先到先執(zhí)行的順序來執(zhí)行。派發(fā)隊(duì)列可以是并發(fā)的或串行的。并發(fā)隊(duì)列可以執(zhí)行多任務(wù),串行隊(duì)列同一時(shí)間只執(zhí)行單一任務(wù)。在GCD中,有3種類型的派發(fā)隊(duì)列。

      串行隊(duì)列。串行隊(duì)列通常用于同步訪問一個(gè)特定的資源,每次只能執(zhí)行一個(gè)任務(wù)。使用函數(shù)dispatch_queue_create,可以創(chuàng)建串行隊(duì)列。

      并發(fā)隊(duì)列。也稱為全局派發(fā)隊(duì)列,可以并發(fā)地執(zhí)行一個(gè)或多個(gè)任務(wù)。并發(fā)隊(duì)列分為高、中、低3個(gè)優(yōu)先級,中級為默認(rèn)級別。可以調(diào)用dispatch_get_global_queue函數(shù)設(shè)定優(yōu)先級來訪問隊(duì)列。dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)語句用于獲得并發(fā)隊(duì)列對象,其中DISPATCH_QUEUE_PRIORITY_DEFAULT是默認(rèn)的優(yōu)先級常量。

      主隊(duì)列。它在應(yīng)用程序的主線程中,用于更新UI。其他的兩個(gè)隊(duì)列不能更新UI。使用dispatch_get_main_queue函數(shù),可以獲得主隊(duì)列。

      我們把BlockDemo工程修改為GCD實(shí)現(xiàn),具體代碼如下:

      BlockDemo工程修改為GCD

      在上述代碼中,dispatch_async函數(shù)用于異步執(zhí)行任務(wù),但是它在串行隊(duì)列中仍然是同步執(zhí)行的。在更新UI時(shí),如self.imageView.image = img語句,dispatch_async函數(shù)必須在主線程中執(zhí)行。我們使用第①行代碼在主隊(duì)列中更新UI。

      通過近幾天的學(xué)習(xí),我們了解了性能優(yōu)化方法,其中包括內(nèi)存優(yōu)化、資源文件優(yōu)化、延遲加載、持久化優(yōu)化、使用可重用對象和并發(fā)訪問等。這些內(nèi)容都是非常重要的,希望對大家有所幫助。了解更多相關(guān)資訊,關(guān)注南昌網(wǎng)絡(luò)公司--百恒網(wǎng)絡(luò)官方網(wǎng)站。百恒網(wǎng)絡(luò)是一家專業(yè)從事南昌網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、網(wǎng)絡(luò)營銷等服務(wù)的南昌網(wǎng)絡(luò)公司,技術(shù)過硬,經(jīng)驗(yàn)豐富。如有任何網(wǎng)站方面的問題,百恒網(wǎng)絡(luò)隨時(shí)歡迎大家來電咨詢,我們專業(yè)為您解答!


      400-680-9298,0791-88117053
      掃一掃關(guān)注百恒網(wǎng)絡(luò)微信公眾號
      掃一掃打開百恒網(wǎng)絡(luò)小程序

      歡迎您的光顧,我們將竭誠為您服務(wù)×

      售前咨詢 售前咨詢
       
      售前咨詢 售前咨詢
       
      售前咨詢 售前咨詢
       
      售前咨詢 售前咨詢
       
      售前咨詢 售前咨詢
       
      售后服務(wù) 售后服務(wù)
       
      售后服務(wù) 售后服務(wù)
       
      備案專線 備案專線
       
      ×
      久久久无码精品亚洲日韩按摩| 国产精品久久久久久久福利院| 久久久国产成人精品| 精品久久久久久无码国产| 精品综合一区二区三区| 欧日韩不卡在线视频| 亚洲无码日韩精品第一页| 国产成人综合久久精品亚洲| 国产精品午夜爆乳美女视频| 2020年国产精品| 国产乱码精品一区二区三区四川人| 久久亚洲精品国产亚洲老地址| 国产福利视精品永久免费| 久久99精品久久久大学生| 91精品国产色综久久| 91精品国产色综久久| 日本中文字幕在线精品| 精品亚洲AV无码一区二区| fulidown国产精品合集| 91精品国产自产在线老师啪| 亚洲av午夜精品无码专区| 久久精品国产四虎| 97久久精品无码一区二区天美 | 日韩精品一区二区三区毛片| 成人精品一区二区三区校园激情 | 亚洲日韩AV一区二区三区四区| 日韩精品无码AV成人观看| 日韩亚洲人成在线| 美女免费精品高清毛片在线视| yy6080久久亚洲精品| 国产久爱免费精品视频| 成人精品一区二区三区中文字幕| 91探花福利精品国产自产在线| 亚洲色精品88色婷婷七月丁香| 九九精品免视看国产成人| 久久免费视频精品| 久久精品国产网红主播| 国产成人精品免费视频大| 欧美日韩精品一区二区在线视频| 自拍偷自拍亚洲精品偷一| 国产国产成人久久精品杨幂|