您好,登錄后才能下訂單哦!
如何編寫多線程應(yīng)用
現(xiàn)在你已經(jīng)知道一個(gè)好的多線程應(yīng)用是怎樣的,它是如何幫助你解決問題的,那么如何編寫一個(gè)好的多線程應(yīng)用呢?我會向你介紹iPhone應(yīng)用中編寫和處理多線程應(yīng)用的主要技術(shù)。
創(chuàng)建一個(gè)線程
為了創(chuàng)建一個(gè)線程,你可以使用下面的方法:
NSThread
POSIX Threads
NSObject 來創(chuàng)建一個(gè)新的線程
NSOperation和NSOperationQueue
我會逐一介紹他們,然后會舉一些例子,因?yàn)樗麄兌加懈髯缘膬?yōu)點(diǎn)和缺點(diǎn)。在本部分結(jié)束的時(shí)候,我會給出一個(gè)表格來進(jìn)行對比,是得你能夠分清他們的不同,這樣在你的需求中就能夠選擇一個(gè)正確的方案。
NSThread
用NSThread創(chuàng)建一個(gè)新的線程,你可以簡單的調(diào)用:
[NSThread detachNewThreadSelector:@selector(threadMethod:) toTarget:self
withObject:nil];
這個(gè)方法會在你的應(yīng)用中創(chuàng)建一個(gè)新的detached線程。一個(gè)detached線程就是它的所有資源會被系統(tǒng)回收,當(dāng)線程存在的時(shí)候。
有些屬性你需要知道。
+(void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
aSelector:當(dāng)線程開始的時(shí)候,這個(gè)方法會在目標(biāo)對象中被調(diào)用。根據(jù)蘋果的文檔,這個(gè)selector只有一個(gè)參數(shù),沒有返回值。
aTarget:將要執(zhí)行在aSelector參數(shù)中所指定的方法的對象。
anArgument:唯一的一個(gè)參數(shù);當(dāng)線程開始的時(shí)候,它會被傳遞到aSelector方法中。
如果你想創(chuàng)建一個(gè)線程,但是不想啟動(dòng)它,你可以使用下面的機(jī)制:
NSThread* myThread = [[NSThread alloc]initWithTarget:self
selector:@selector(myThreadMainMethod:)object:nil];
[myThread start]; // Actually create the thread
你可以看到,第一行,你創(chuàng)建了一個(gè)新的線程,然后,根據(jù)你的選擇,你可以在對象上調(diào)用start來啟動(dòng)一個(gè)新的線程。這是非常有用的,如果你只想傳遞myThread對象,而不想傳遞selector,target和argument的話。
另一個(gè)比較好的做法是,使用NSThread對象發(fā)送一個(gè)消息給線程對象
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thrwithObject:(id)arg waitUntilDone:(BOOL)wait
這個(gè)方法會在另一個(gè)線程上queue selector。當(dāng)系統(tǒng)自動(dòng)運(yùn)行線程時(shí),線程會dequeue這個(gè)消息,然后會調(diào)用aSelector變量指定的方法。
使用POSIX線程
這個(gè)在iPhone應(yīng)用中主要是用c編程時(shí)會用到。在第9章,我會更深入的討論c編程,并能夠幫助你在很多情況下提升你的iPhone apps的性能。所以這個(gè)部分可能不會幫助你太多,如果你還不了解c編程的話。如果你已經(jīng)了解了c編程,Listing 6-3 展示了代碼,后面會有一個(gè)解釋。
Listing 6–3. POSIX Thread#include <assert.h>
#include <pthread.h>
void* ThreadMethod(void* data){
// Your main logic comes here.
return NULL;
}
void LaunchThread(){
// Create the thread using POSIX routines.
pthread_attr_t attr;
pthread_t posixThreadID;
int returnVal;
// init and check if init a new thread successful
returnVal = pthread_attr_init(&attr);
assert(!returnVal);
// set attribute detach state for new thread
returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
assert(!returnVal);
// create and run the new thread
int threadError = pthread_create(&posixThreadID, &attr, &ThreadMethod, NULL);
returnVal = pthread_attr_destroy(&attr);
assert(!returnVal);
if (threadError != 0)
{
// Report an error.
}
}
NSObject
所有的對象都可以創(chuàng)建和detach一個(gè)新的線程來執(zhí)行這些對象的selectors。你可以使用下面的這行代碼在后臺線程中運(yùn)行doSomething方法:
[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];
調(diào)用這個(gè)方法的效果和下面的這行代碼是一樣的:
[NSThread detachNewThreadSelector:@selector(doSomething) toTarget:myObj withObject:nil]
這個(gè)方法是比較好的,對于detach和創(chuàng)建一個(gè)運(yùn)行后臺任務(wù)的線程來說。
NSOperationQueue
NSOperationQueue是管理和運(yùn)行并發(fā)任務(wù)的一個(gè)機(jī)制。NSOperationQueue的一個(gè)好處是它能夠限制系統(tǒng)內(nèi)部并發(fā)operations的數(shù)量,通過給定一個(gè)限制使得系統(tǒng)加載在一個(gè)可以接受的范圍水平。因?yàn)檫@個(gè)最大線程數(shù)量的限制,如果有更多的線程實(shí)例,NSOperationQueue不會導(dǎo)致更多的并發(fā)線程同時(shí)在系統(tǒng)中運(yùn)行。
你可以在queue中添加operations,但是不能刪除。然而,你可以在queue中取消所有已經(jīng)存在的和還沒有運(yùn)行的operations。表格 6-2 展示了當(dāng)使用NSOperationQueue時(shí),一些非常有用的方法。
你可以用3個(gè)不同的類來使用NSOperationQueue。
NSInvocationOperation:如果你已經(jīng)有一個(gè)對象和一個(gè)方法加入到一個(gè)并發(fā)線程中,這只是一個(gè)簡單的包裹。它不需要子類,所以通過這個(gè)類來創(chuàng)建一個(gè)簡單的NSOperation對象。NSInvocationOperation是NSOperation的子類。
NSBlockOperation:這是另一包裹類,用來執(zhí)行一個(gè)或多個(gè)blocks,而不需要?jiǎng)?chuàng)建一個(gè)單獨(dú)的NSOperation對象來執(zhí)行每一個(gè)block。當(dāng)執(zhí)行超過一個(gè)block時(shí),只有所有內(nèi)部的blocks都執(zhí)行完畢,那么NSBlockOperation才被認(rèn)為結(jié)束了。
Custom NSOperation:NSOperation是一個(gè)基類。通過繼承它,你能夠完全的控制整個(gè)NSOperation對象的實(shí)現(xiàn),包括你的operation執(zhí)行說的默認(rèn)行為和報(bào)告它的狀態(tài)。
使用NSOperationQueue進(jìn)行多線程設(shè)計(jì),你需要用這3個(gè)方法中的一個(gè)來創(chuàng)建指定的對象,然后把新創(chuàng)建的NSOperation加入到你的queue中。然后這個(gè)queue會為你維護(hù)和運(yùn)行這些operations。
這里有一個(gè)簡單的代碼來幫助你創(chuàng)建一個(gè)NSOperationQueue,然后把相互獨(dú)立的operation對象放進(jìn)去,來創(chuàng)建一個(gè)多線程環(huán)境:
NSOperationQueue* myOperationQueue = [[NSOperationQueue alloc] init];
[myOperationQueue addOperation:myOperation]; // Add a single operation
[myOperationQueue addOperations:arrayOfOperations waitUntilFinished:NO]; // Add multipleoperations
[aQueue addOperationWithBlock:^{
/* Do Something. */
}];
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。