您好,登錄后才能下訂單哦!
如何編寫多線程應用
現在你已經知道一個好的多線程應用是怎樣的,它是如何幫助你解決問題的,那么如何編寫一個好的多線程應用呢?我會向你介紹iPhone應用中編寫和處理多線程應用的主要技術。
創建一個線程
為了創建一個線程,你可以使用下面的方法:
NSThread
POSIX Threads
NSObject 來創建一個新的線程
NSOperation和NSOperationQueue
我會逐一介紹他們,然后會舉一些例子,因為他們都有各自的優點和缺點。在本部分結束的時候,我會給出一個表格來進行對比,是得你能夠分清他們的不同,這樣在你的需求中就能夠選擇一個正確的方案。
NSThread
用NSThread創建一個新的線程,你可以簡單的調用:
[NSThread detachNewThreadSelector:@selector(threadMethod:) toTarget:self
withObject:nil];
這個方法會在你的應用中創建一個新的detached線程。一個detached線程就是它的所有資源會被系統回收,當線程存在的時候。
有些屬性你需要知道。
+(void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
aSelector:當線程開始的時候,這個方法會在目標對象中被調用。根據蘋果的文檔,這個selector只有一個參數,沒有返回值。
aTarget:將要執行在aSelector參數中所指定的方法的對象。
anArgument:唯一的一個參數;當線程開始的時候,它會被傳遞到aSelector方法中。
如果你想創建一個線程,但是不想啟動它,你可以使用下面的機制:
NSThread* myThread = [[NSThread alloc]initWithTarget:self
selector:@selector(myThreadMainMethod:)object:nil];
[myThread start]; // Actually create the thread
你可以看到,第一行,你創建了一個新的線程,然后,根據你的選擇,你可以在對象上調用start來啟動一個新的線程。這是非常有用的,如果你只想傳遞myThread對象,而不想傳遞selector,target和argument的話。
另一個比較好的做法是,使用NSThread對象發送一個消息給線程對象
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thrwithObject:(id)arg waitUntilDone:(BOOL)wait
這個方法會在另一個線程上queue selector。當系統自動運行線程時,線程會dequeue這個消息,然后會調用aSelector變量指定的方法。
使用POSIX線程
這個在iPhone應用中主要是用c編程時會用到。在第9章,我會更深入的討論c編程,并能夠幫助你在很多情況下提升你的iPhone apps的性能。所以這個部分可能不會幫助你太多,如果你還不了解c編程的話。如果你已經了解了c編程,Listing 6-3 展示了代碼,后面會有一個解釋。
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
所有的對象都可以創建和detach一個新的線程來執行這些對象的selectors。你可以使用下面的這行代碼在后臺線程中運行doSomething方法:
[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];
調用這個方法的效果和下面的這行代碼是一樣的:
[NSThread detachNewThreadSelector:@selector(doSomething) toTarget:myObj withObject:nil]
這個方法是比較好的,對于detach和創建一個運行后臺任務的線程來說。
NSOperationQueue
NSOperationQueue是管理和運行并發任務的一個機制。NSOperationQueue的一個好處是它能夠限制系統內部并發operations的數量,通過給定一個限制使得系統加載在一個可以接受的范圍水平。因為這個最大線程數量的限制,如果有更多的線程實例,NSOperationQueue不會導致更多的并發線程同時在系統中運行。
你可以在queue中添加operations,但是不能刪除。然而,你可以在queue中取消所有已經存在的和還沒有運行的operations。表格 6-2 展示了當使用NSOperationQueue時,一些非常有用的方法。
你可以用3個不同的類來使用NSOperationQueue。
NSInvocationOperation:如果你已經有一個對象和一個方法加入到一個并發線程中,這只是一個簡單的包裹。它不需要子類,所以通過這個類來創建一個簡單的NSOperation對象。NSInvocationOperation是NSOperation的子類。
NSBlockOperation:這是另一包裹類,用來執行一個或多個blocks,而不需要創建一個單獨的NSOperation對象來執行每一個block。當執行超過一個block時,只有所有內部的blocks都執行完畢,那么NSBlockOperation才被認為結束了。
Custom NSOperation:NSOperation是一個基類。通過繼承它,你能夠完全的控制整個NSOperation對象的實現,包括你的operation執行說的默認行為和報告它的狀態。
使用NSOperationQueue進行多線程設計,你需要用這3個方法中的一個來創建指定的對象,然后把新創建的NSOperation加入到你的queue中。然后這個queue會為你維護和運行這些operations。
這里有一個簡單的代碼來幫助你創建一個NSOperationQueue,然后把相互獨立的operation對象放進去,來創建一個多線程環境:
NSOperationQueue* myOperationQueue = [[NSOperationQueue alloc] init];
[myOperationQueue addOperation:myOperation]; // Add a single operation
[myOperationQueue addOperations:arrayOfOperations waitUntilFinished:NO]; // Add multipleoperations
[aQueue addOperationWithBlock:^{
/* Do Something. */
}];
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。