多執行緒的使用與注意事項
從例子入手
多執行緒程式的控制模型可以參考[url=這裡[/url],一般情況下都是使用 管理者/工人模型, 這裡,我們使用iphone sdk中的 nsthread 來實現它。
[img]
接下來,在 tutorialprojectviewcontroller.h 檔案中建立各個ui控制項的 iboutlets.
@inte***ce tutorialprojectviewcontroller : uiviewcontroller
同時,也需要建立outlets變數的property.
@property (nonatomic, retain) iboutlet uilabel *threadvaluelabel;
@property (nonatomic, retain) iboutlet uiprogressview *threadprogressview;
@property (nonatomic, retain) iboutlet uiprogressview *threadstartbutton;
@property (nonatomic, retain) iboutlet uilabel *testvaluelabel;
接下來定義按鈕按下時的動作函式,以及slider的變化函式。
- (ibaction) startthreadbuttonpressed:(uibutton *)sender;
- (ibaction) testvaluesliderchanged:(uislider *)sender;
然後在 tutorialprojectviewcontroller.m 檔案中synthesize outlets,並在檔案為實現dealloc釋放資源。
@synthesize threadvaluelabel, threadprogressview, testvaluelabel, threadstartbutton;
...- (void)dealloc
現在開始執行緒部分的**,首先當 thread button 被按下的時候,建立新的執行緒.
- (ibaction) startthreadbuttonpressed:(uibutton *)sender
該按鈕被按下後,隱藏按鈕以禁止多次建立執行緒。然後初始化顯示值和進度條,最後建立新的執行緒,執行緒的函式為 startthebackgroundjob.
具體的 startthebackgroundjob 函式定義如下.
- (void)startthebackgroundjob
最後一行,阻塞呼叫(waituntildone狀態是on)函式 makemyprogressbarmoving。
- (void)makemyprogressbarmoving
else threadstartbutton.hidden = no;
}
這裡計算用於顯示的進度條的值,利用 nstimer ,每0.5秒自增0.01,當值等於1的時候,進度條為100%,退出函式並顯示剛才被隱藏的按鈕。
最後,新增 uislider 的實現函式,用來更改主線程中 test part 中的 label 值
- (ibaction) testvaluesliderchanged:(uislider *)sender
編譯執行,按下執行緒開始按鈕,你將看到進度條的計算是在後台執行。
[img]
[size=large][color=black][b]使用執行緒的注意事項[/b][/color][/size]
[b]執行緒的堆疊大小[/b]iphone裝置上的應用程式開發也是屬於嵌入式裝置的開發,同樣需要注意嵌入式裝置開發時的幾點問題,比如資源上限,處理器速度等。
iphone 中的執行緒應用並不是無節制的,官方給出的資料顯示iphone os下的主線程的堆疊大小是1m,第二個執行緒開始都是512kb。並且該值不能通過編譯器開關或執行緒api函式來更改。
你可以用下面的例子測試你的裝置,這裡使用posix thread(pthread),裝置環境是 iphone 3gs(16gb)、sdk是3.1.3。
結果如下:
[b]模擬器[/b]
main thread: base:0xc0000000 / size:524288
rlimit-> soft:8388608 / hard:67104768
thread: base:0xb014b000 / size:524288
[b]裝置[/b]
main thread: base:0x30000000 / size:524288
rlimit-> soft:1044480 / hard:1044480
thread: base:0xf1000 / size:524288
由此可見,當你測試多執行緒的程式時,模擬器和實際裝置的堆疊大小是不一樣的。如果有大量遞迴函式呼叫可要注意了。
[b]autorelease[/b]
nsautoreleasenopool(): object 0x********* of class nsconretedata autoreleased with no pool in place ….
nsautoreleasepool *pool = [[nsautoreleasepool alloc]init];
[size=large][b]子執行緒中描畫視窗[/b][/size]
多執行緒程式設計中普遍遵循乙個原則,就是一切與ui相關的操作都有主線程做,子執行緒只負責事務,資料方面的處理。那麼如果想在子執行緒中更新ui時怎麼做呢?如果是在windows下,你會 postmessage 乙個描畫更新的訊息,在iphone中,需要使用performselectoronmainthread 委託主線程處理。
imageview.image = [uiimage imagenamed:@"hoge.png"];
這麼做,什麼也不會出現的。需要將該處理委託給主線程來做,像下面:
[delegate performselectoronmainthread:@selector(theprocess:) withobject:nil waituntildone:yes];
就ok了
1. drain 與 release 的區別前提是你的系統中是否有gc,如果有,-drain 需要送乙個訊息給gc (objc_collect_if_needed),而如果沒有gc,drain = release
多執行緒的使用與注意事項
多執行緒程式的控制模型可以參考這裡,一般情況下都是使用 管理者 工人模型,這裡,我們使用iphone sdk中的 nsthread 來實現它。接下來,在 tutorialprojectviewcontroller.h 檔案中建立各個ui控制項的 iboutlets.123 4567 891011 1...
多執行緒使用注意事項
在開發過程中經常使用到多執行緒。對ios的多執行緒有很多不解的地方,這裡暫且記錄下來。具體原因有待以後慢慢研究。void scanloop pool release 以asyncudpsocket物件為引數的處理函式,如下所示 void processipscanwithsocket asyncud...
多執行緒程式設計注意事項
1 明確目的,為什麼要使用多執行緒?如果是由於單執行緒讀寫或者網路訪問 例如http訪問網際網路 的瓶頸,可以考慮使用執行緒池。如果是對不同的資源 例如socket連線 進行管理,可以考慮多個執行緒。2 執行緒使用中要注意,如何控制線程的排程和阻塞,例如利用事件的觸發來控制線程的排程和阻塞,也有用訊...