2011-08-13 73 views
2

我有一個多線程應用程序,其中每個線程都必須執行一些工作,但在某個點上需要連續執行一些代碼(如寫入sqlite3要使用在主線程上執行的數據庫),所以我打電話的代碼:使用除主線程以外的應用程序生命週期線程

[self performSelectorOnMainThread:@selector(serialJob:) withObject:object waitUntilDone:YES]; 

和每一件事情去除了就好了,當代碼需要一些時間,直到該代碼與應用程序的用戶交互被禁用已經完成了,那麼是否有任何方法可以創建另一個可以在後臺運行的ONE線程,並且可以在需要時隨時調用,就像主線程一樣,以便我可以用以下代碼替換之前的調用:

[self performSelector:@selector(serialJob:) onThread:REQUIRED_THREAD withObject:object waitUntilDone:YES]; 

這個線程應該是某些類的靜態數據成員,可以從整個代碼中訪問。

任何幫助將是非常讚賞,並提前許多感謝...

回答

0

由於我的問題,我需要當前線程被阻止,直到數據庫作業完成,我已經嘗試了這兩種解決方案,他們完美地工作。您可以使用臨界區或NSOperationQueue,我更喜歡第一個,這裏是他們兩人的代碼:

定義一些類「DatabaseController」這個代碼添加到它的實現:

static NSString * DatabaseLock = nil; 
+ (void)initialize { 
    [super initialize]; 
    DatabaseLock = [[NSString alloc] initWithString:@"Database-Lock"]; 
} 
+ (NSString *)databaseLock { 
    return DatabaseLock; 
} 

- (void)writeToDatabase1 { 
    @synchronized ([DatabaseController databaseLock]) { 
     // Code that writes to an sqlite3 database goes here... 
    } 
} 
- (void)writeToDatabase2 { 
    @synchronized ([DatabaseController databaseLock]) { 
     // Code that writes to an sqlite3 database goes here... 
    } 
} 

OR使用NSOperationQueue你可以使用:

static NSOperationQueue * DatabaseQueue = nil; 
+ (void)initialize { 
    [super initialize]; 

    DatabaseQueue = [[NSOperationQueue alloc] init]; 
    [DatabaseQueue setMaxConcurrentOperationCount:1]; 
} 
+ (NSOperationQueue *)databaseQueue { 
    return DatabaseQueue; 
} 

- (void)writeToDatabase { 
    NSInvocationOperation * operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(FUNCTION_THAT_WRITES_TO_DATABASE) object:nil]; 
    [operation setQueuePriority:NSOperationQueuePriorityHigh]; 
    [[DatabaseController databaseQueue] addOperations:[NSArray arrayWithObject:operation] waitUntilFinished:YES]; 
    [operation release]; 
} 

這兩種解決方案阻止當前線程,直到寫入數據庫完成後,你可以在大多數的情況下考慮。

2

這是很容易做到的,只是產卵你的線程並讓它運行它的runloop使用[[NSRunLoop currentRunLoop] run]。這就是能夠使用performSelector:onThread:與自定義線程所需的全部內容。

如果你在iOS 4或更新的版本,你應該考慮使用Grand Central Dispatch隊列,而不是線程。 GCD API更容易使用,並且可以更好地利用系統資源。

+0

請問您可以寫一個關於如何創建該線程的示例代碼(假設在applicationDelegate中),並將其初始化爲在應用程序的生命週期中運行,而不管我在生命週期中創建了多少個操作。我的意思是應該在應用程序完成加載時創建該線程,並在關閉時刪除該線程。 – Mousa

1

像Sven提到的,看看Grand Central Dispatch

您可以創建這樣的隊列:

dispatch_queue_t myQueue = dispatch_queue_create("com.yourcompany.myDataQueue", NULL); 

現在,您可以撥打該隊列塊:

dispatch_async(myQueue, ^{ 
    // Your code to write to DB. 
}); 

當您完成後,不要忘記釋放隊列:

dispatch_release(myQueue); 
+0

感謝你的回答,但是這段代碼是否使當前線程等待寫入數據庫的代碼完成?正如我在使用waitUntilDone設置爲YES來完成此問題中提到的那樣。並再次感謝 – Mousa

相關問題