青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 319, comments - 22, trackbacks - 0, articles - 11
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

隔上一次寫iPad app開發(fā)文章已經(jīng)是10個月,那篇iPad app開發(fā)概述還不錯,曾經(jīng)成為了google關(guān)鍵字“iPad app 開發(fā)”搜索的第一位,可能是大牛們都太忙于賺app store的錢了,留下我這個小蝦來寫文章。這次的文章集中與iOS的多核編程和內(nèi)存管理,為什么?因?yàn)閕Pad 2已經(jīng)是雙核CPU了!雖然iPad 1的應(yīng)用已經(jīng)不慢了,但大家完全可以使用蘋果的多核編程框架來寫出更加responsive的應(yīng)用。

 

多核運(yùn)算

在iOS中concurrency編程的框架就是GCD(Grand Central Dispatch), GCD的使用非常簡單。它把任務(wù)分派到不同的queue隊(duì)列來處理。開發(fā)者把任務(wù)代碼裝到一個個block里面,操作系統(tǒng)把這些任務(wù)代碼分派到不同的資源里去處理,一個簡單的例子來說,為什么初學(xué)者寫tableview的時候,滑動列表時總會很卡,因?yàn)楹芏喑鯇W(xué)者把圖片裝載放到main thread主線程去執(zhí)行,例如我們要滑動暢順的話,iOS最快可以1秒內(nèi)刷新60次,如何你的一個cell的文字和圖片裝載超過1/60秒的話,自然就會卡。所以一般我們會把圖片裝載這些需要多點(diǎn)時間的移出main thread來處理,對于用GCD來說,就是把圖片載入放到另外一個queue隊(duì)列中來異步執(zhí)行,當(dāng)資源準(zhǔn)備好了后,放回到main thread中顯示出來。main thread在GCD中就是main queue。

 

創(chuàng)建一個新queue隊(duì)列的代碼:

 

 

C代碼  收藏代碼
  1. dispatch_queue_t network_queue;  
  2.   
  3. network_queue = dispatch_queue_create("com.myapp.network", nill);  

 

例如,我們圖片讀取放到network_queue來進(jìn)行異步執(zhí)行

 

 

C代碼  收藏代碼
  1. dispatch_async(network_queue, ^{    
  2.     UIImage *cellImage = [self loadMyImageFromNetwork:image_url];    
  3.     // 將圖片cache到本地    
  4.     [self cacheImage:cellImage];    
  5.     
  6.     .....    
  7.         
  8. } );  
 

 

dispatch_async的意思就是將任務(wù)進(jìn)行異步并行處理,不一定需要一個任務(wù)處理完后才能處理下一個。以上代碼loadMyImageFromNetwork的意思就是從網(wǎng)絡(luò)中讀取圖片,這個任務(wù)交給network_queue來處理。這樣讀取圖片的時間過長也不會阻塞主線程界面的處理。

 

當(dāng)我們處理完圖片后,應(yīng)該更新界面,從queue的概念去設(shè)計(jì),就是要將更新界面的代碼放到main queue中去,因?yàn)閕OS里面永遠(yuǎn)是主線程來刷新重畫UI。所以代碼應(yīng)該為,

 

 

C代碼  收藏代碼
  1. dispatch_async(network_queue, ^{    
  2.     UIImage *cellImage = [self loadMyImageFromNetwork:image_url];    
  3.     // 將圖片cache到本地    
  4.     [self cacheImage:cellImage];    
  5.     
  6.    // 回到主線程    
  7.    dispatch_async(dispatch_get_main_queue(), ^{    
  8.       // 顯示圖片到界面    
  9.       [self displayImageToTableView:cellImage];    
  10.    }];    
  11.         
  12. } );  
 

 

dispatch_get_main_queue() 函數(shù)就是返回主線程,^{} 封裝的就是任務(wù)代碼,這樣嵌套方式就可以從一個隊(duì)列queue,跳到另一個queue,就是這么簡單。

 

我們一般可以把networking有關(guān)的代碼放到一個queue,把圖片resize的代碼放到另外一個queue,處理完后更新界面,只需要嵌套跳回到 main queue。這樣加上幾行代碼,你的程序就可以利用到系統(tǒng)多核資源,把具體的調(diào)度工作交給了操作系統(tǒng)自己來分配。有了這樣的代碼,不管你的硬件是單核,雙核還是iMac的4核,甚至8核,都可以非常好地并行處理。

 

 

內(nèi)存管理

我一直驚嘆iOS和Objective-C內(nèi)存處理能力,例如iPad版本的iWork,Pages應(yīng)用就是一個內(nèi)存處理技術(shù)應(yīng)用的鬼斧神工之作。想想256M內(nèi)存的iPad,可以帶來如此的華麗的界面同時獲得如此流暢的用戶體驗(yàn),真是不簡單。原因就是iOS一直提倡開發(fā)者在有限硬件資源內(nèi)寫出最優(yōu)化的代碼,使用CPU最少,占用內(nèi)存最小。

 

(以下代碼適用于iOS SDK 4.1, 由于新SDK 4.2對內(nèi)存使用有新改動,所以可能有不同。。。)

1. 盡量少的UIView層

通常我們喜歡把很多控件層(UILabel,UIButton,UIView等)一起放到一個大的UIView容器來顯示我們的內(nèi)容,這個方法一般是可以的,但是如果要經(jīng)常重新刷新內(nèi)容的大區(qū)域界面,多數(shù)發(fā)生在iPad的應(yīng)用中,這個方法會帶來過多的內(nèi)存使用和動畫的延遲(比較卡),例如,scrollview的動畫比較卡,又或者,經(jīng)常收到內(nèi)存警告。其中一個重要原因是每個控件,特別是透明底的,會多次重新繪制(drawRect)過多。其解決辦法是,盡量將幾個控件合并到一個層上來顯示,這樣系統(tǒng)會減少系統(tǒng)調(diào)用drawRect,從而帶來性能上的提升。

 

很簡單的一個例子,就是iNotes提供手寫功能,用戶可以在iPad屏幕上寫出不同的筆畫,開始的設(shè)計(jì)是,用戶每寫一劃,iNotes就會生成一個新的透明底UIView來保持這個筆畫,用戶寫了10筆,系統(tǒng)就生產(chǎn)了10個UIView,每個view的大小都是整個屏幕的,以便用戶的undo操作。這個方案帶來嚴(yán)重的內(nèi)存問題,因?yàn)橄到y(tǒng)將每個層都保持一個bitmap圖,一個像素需要4bit來算,一個層的大小就是 4x1024x768 ~ 3M, 10個層就是 10x3M = 30M,很明顯,iPad很快爆出內(nèi)存警告。

 

這個例子最后的方案是,所有筆畫都畫在同一個層,iNotes可以保存筆畫的點(diǎn)進(jìn)行undo操作。這樣的方案就是無論用戶畫多少筆畫,界面重畫需要的資源都是一樣的。

 

2. 顯示最佳尺寸的圖片

很多程序員比較懶,網(wǎng)絡(luò)上拿下來的圖片,直接就用UIImageView將其顯示給用戶,這樣的后果就是,程序需要一直保存著大尺寸的圖片到內(nèi)存。解決辦法應(yīng)該是先將圖片縮小到需要顯示的尺寸,釋放大尺寸圖片的內(nèi)存,然后再顯示到界面給用戶。

 

3. 盡量使用圖片pattern,而不是一張大的圖片

例如,很多界面設(shè)計(jì)者喜歡在界面上放一個大底圖,但這個底圖是老是占用著內(nèi)存的,最佳方案是,設(shè)計(jì)出一個小的pattern圖,然后用這個方案顯示成底圖。

 

C代碼  收藏代碼
  1. UIImage *smallImage = [[UIImage alloc] initWithContentsOfFile:path];  
  2.   
  3. backgroundView.backgroundColor = [UIColor colorWithPatternImage:smallImage];  
  4.   
  5. [smallImage release];  
 

 

4. 使用完資源后,立即釋放

一般objective-c的習(xí)慣是,用完的資源要立即釋放,因?yàn)槊靼资裁磿r候用完某個資源的是程序員你自己。

例如,我們要讀較大的圖片,把它縮小后,顯示到界面去。當(dāng)大圖片使用完成后,應(yīng)該立即釋放。代碼如下:

 

C代碼  收藏代碼
  1. UIImage *fullscreenImage = [[UIImage alloc] initWithContentOfFile:path];  
  2. UIImage *smallImage = [self resizeImage:fullscreenImage];  
  3.   
  4. [fullscreenImage release];  
  5.   
  6. imageView.image = smallImage;  
  7.   
  8. ......  
 

5. 循環(huán)中大量生成的自動釋放autorelease對象,可以考慮使用autorelease pool封裝

代碼范例:

C代碼  收藏代碼
  1. for(UIView *subview in bigView.subviews) {  
  2.     // 使用autorelease pool自動釋放對象池  
  3.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
  4.   
  5.     UIImageView *imageView = (UIImageView *)subview;  
  6.       
  7.     // subview處理代碼  
  8.     .......  
  9.   
  10.     // 銷毀自動釋放對象  
  11.     [pool  drain];  
  12. }  

 自動釋放對象池把每個循環(huán)內(nèi)生成的臨時對象使用完后立即釋放

 

以上的意見是本人多年來編寫iPad/iPhone程序的經(jīng)驗(yàn),另外iOS4.0的multi-tasking特性發(fā)布后,程序可以被調(diào)入后臺運(yùn)行,蘋果工程師的意見是,進(jìn)入后臺運(yùn)行時,你的應(yīng)用應(yīng)該釋放掉能釋放的對象,盡量保持在16M左右,這樣別的程序運(yùn)行時才不容易把你的應(yīng)用擠掉。

 

--------------------------------------------------

太久沒有寫東西了,中文寫作能力退步了,大家別見怪,多給給意見

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一区二区毛片| 亚洲乱码国产乱码精品精| 欧美日韩在线精品| 欧美成人精品一区| 国产一区二区日韩| 亚洲一区二区网站| 亚洲综合欧美| 欧美日韩直播| 亚洲精品少妇| 日韩视频国产视频| 欧美大片网址| 亚洲高清激情| 在线成人中文字幕| 久久久午夜精品| 久久在精品线影院精品国产| 国产一区二区高清不卡| 香蕉乱码成人久久天堂爱免费| 亚洲小说区图片区| 欧美午夜激情小视频| 一区二区三区视频在线看| 亚洲视频在线观看| 欧美午夜a级限制福利片| 99riav久久精品riav| 亚洲午夜激情| 国产精品成人在线观看| 亚洲小说欧美另类社区| 亚洲欧美一区二区精品久久久 | 久久久久9999亚洲精品| 久久精品国产综合精品| 国产亚洲精品高潮| 久久九九国产精品| 欧美成人精品福利| 亚洲精品久久久蜜桃| 欧美日韩国产欧美日美国产精品| 亚洲精品美女91| 亚洲一区在线免费| 国产精品久久久久久久免费软件 | 欧美激情一区二区三区| 亚洲国产视频直播| 亚洲无人区一区| 国产日韩精品一区二区浪潮av | 欧美一级片在线播放| 久久免费高清视频| 亚洲美女av黄| 国产精品综合久久久| 久久精品国产欧美激情| 亚洲国产精品999| 亚洲一区亚洲二区| 狠狠色丁香婷婷综合| 欧美精品一区二区在线观看| 亚洲与欧洲av电影| 欧美激情亚洲激情| 午夜精品亚洲一区二区三区嫩草| 激情综合网激情| 欧美视频一二三区| 久久精品水蜜桃av综合天堂| 亚洲精品自在在线观看| 久久久久高清| 中文欧美日韩| 在线精品在线| 国产精品久久久久久久久久ktv| 久久久久久久久综合| 亚洲最新中文字幕| 欧美大尺度在线| 香蕉久久精品日日躁夜夜躁| 亚洲人精品午夜| 国产网站欧美日韩免费精品在线观看 | 亚洲激情网站免费观看| 久久久999成人| 亚洲视频网在线直播| 亚洲第一福利社区| 国产精品入口福利| 欧美精品性视频| 久久噜噜亚洲综合| 西西裸体人体做爰大胆久久久| 亚洲三级视频在线观看| 麻豆91精品| 久久精品av麻豆的观看方式| 亚洲一区二区视频在线观看| 亚洲高清不卡在线| 好吊妞**欧美| 国产精品羞羞答答| 欧美日韩在线免费| 欧美精品不卡| 麻豆国产精品va在线观看不卡| 欧美一进一出视频| 亚洲欧美在线高清| 亚洲一区二区三区免费在线观看 | 欧美日本免费一区二区三区| 久久综合伊人77777| 久久都是精品| 欧美一区三区三区高中清蜜桃| 中文在线一区| 一区二区欧美日韩视频| 日韩视频欧美视频| 日韩午夜在线电影| 99成人在线| 99精品视频免费观看视频| 亚洲美女精品一区| 亚洲另类视频| 99视频精品全部免费在线| 日韩视频免费大全中文字幕| 亚洲美女av黄| 这里只有视频精品| 国产精品99久久久久久久vr| 亚洲一区二区四区| 香蕉成人久久| 久久久久一区二区| 美女诱惑黄网站一区| 欧美高清hd18日本| 欧美三区在线视频| 国产精品男gay被猛男狂揉视频| 国产精品视频免费观看www| 国产精品一区久久久久| 国产一区二区三区在线播放免费观看| 国产亚洲一区在线| 亚洲国产精品成人精品| 夜夜嗨av一区二区三区四季av| 一本色道久久综合亚洲精品高清| 一区二区三区欧美日韩| 午夜视频一区二区| 久久久久久一区二区三区| 欧美福利一区二区| 日韩视频三区| 欧美与黑人午夜性猛交久久久| 久久尤物视频| 欧美视频在线观看视频极品| 国产欧美在线视频| 亚洲国产精品一区二区第一页| 99精品热视频只有精品10| 亚洲欧美成aⅴ人在线观看| 久久精品视频va| 亚洲国产另类久久久精品极度| 一个色综合导航| 久久国产精品一区二区三区四区| 欧美不卡视频| 国产精品色午夜在线观看| 在线播放一区| 亚洲欧美日韩国产中文| 麻豆久久精品| 一区二区三区四区国产精品| 欧美一区精品| 欧美精品电影| 极品日韩久久| 亚洲欧美国产视频| 欧美成ee人免费视频| 亚洲午夜精品国产| 毛片基地黄久久久久久天堂| 国产精品免费看久久久香蕉| 亚洲国产一区在线| 欧美一区二区视频免费观看| 亚洲国产精品一区二区第一页| 亚洲欧美精品伊人久久| 欧美精品亚洲精品| 伊人久久婷婷色综合98网| 午夜日本精品| 日韩视频精品在线| 你懂的成人av| 精品成人一区| 欧美在线视频免费| 日韩视频永久免费| 欧美高清视频在线 | 国产日韩精品久久| 亚洲国产精品久久久久秋霞影院 | 亚洲高清不卡| 久久精品国产96久久久香蕉| 国产精品久久久久久妇女6080 | 亚洲另类春色国产| 久久婷婷麻豆| 狠狠色狠色综合曰曰| 午夜精品视频在线| a91a精品视频在线观看| 欧美黄色片免费观看| 在线成人欧美| 久久久久五月天| 午夜精品视频| 国产免费一区二区三区香蕉精| 亚洲一区bb| 一本大道av伊人久久综合| 欧美成人有码| 亚洲人在线视频| 欧美国产在线观看| 美女视频黄免费的久久| 亚洲国产裸拍裸体视频在线观看乱了中文 | 久久国产99| 午夜精品国产更新| 国产欧美69| 久久精品视频在线播放| 欧美在线www| 一区视频在线看| 欧美大片18| 欧美成ee人免费视频| 亚洲伦伦在线| 一本色道婷婷久久欧美| 国产精品av久久久久久麻豆网| 亚洲午夜伦理| 亚洲欧美日韩精品一区二区| 国产亚洲午夜高清国产拍精品| 久久久久久国产精品一区| 久久久www成人免费无遮挡大片 |