2012-06-21 55 views
1

我有一個任務正在從磁盤讀取,可能需要相當長的一段時間,所以不想在主線程中完成它。我想要的是在從磁盤讀取後調用函數X 。在iOS中執行此操作的最佳方法是什麼?在後臺線程中運行並有一個完成塊?

到目前爲止,這是我已經試過:

NSInvocationOperation *processDataOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(readDisk:) object:nil]; 
       [processDataOperation setQueuePriority:NSOperationQueuePriorityVeryHigh]; 
       [processDataOperation setCompletionBlock:^(void){ 
        NSMutableArray *feedItemsArray = [self generateFeedItemsFromDictionary:streamDiskData]; 
        [self postFetchCompletedNotificationForDict:queryStringDict withFeedItems:feedItemsArray isFresh:NO]; 
       }]; 

基本上我使用NSInvocationOperation,然後設置它的建成塊,但問題是,在我完成塊我需要在生成的結果readDisk。我如何在完成塊中訪問它?這幾乎是不可能的權利?

+0

你已經試過了什麼代碼? – Linuxios

回答

7

使用NSInvocations可以實現超出主線程的微不足道的工作。

GCD和NSOperations都可用於實現各種各樣的併發策略。從面向對象的角度來看,NSOperations比CGD塊更高度抽象,這使得它們(imo)更易於「設計」,並且可能超出了我實現它們的範圍。 GCD是較低級別的:這使得與它的交互看起來稍微複雜一些(但實際上並不是這樣),但那些處理這些事情的人會告訴你它「更高效」並且帶來「更少的開銷」。

我個人的做法是在我的應用程序中有一個設計/協調的併發模式,並使用GCD進行簡單的併發/後臺操作的場景中使用NSOperations。

如果我所需要做的是激發一些與設計無關的任務,但需要在後臺完成,我會使用CGD。這就是我可能在這種情況下使用的:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 

    [self readDisk]; 
    NSMutableArray *feedItemsArray = [weakSelf generateFeedItemsFromDictionary:streamDiskData]; 

     dispatch_sync(dispatch_get_main_queue(), ^{ 

     //Call back to the main thread before performing/posting anything touching UIKit 
     [self postFetchCompletedNotificationForDict:queryStringDict withFeedItems:feedItemsArray isFresh:NO]; 
     }) 
})]; 
+0

我可以知道你爲什麼創建__unsafe __unretained weakSelf = self; 而不是直接在blokc裏面使用self? – xonegirlz

+0

當然 - 該塊將「複製」它引用的對象,這會聲明所有權。這意味着自己擁有該塊,但該塊也擁有自己:這是保留循環的要素。通過在塊中明確地引用自我,我們避免了這種可能性。 – isaac

+0

所以最好的做法是在塊中使用self時使用弱引用? – xonegirlz

0

您可以隨時使用grand central dispatch在後臺執行操作。

由於它是一個塊,您可以正常調用該方法並存儲結果。然後抓取主隊列,如果你需要更新任何用戶界面或完成後做任何你需要的。

dispatch_queue_t queue = dispatch_queue_create("read disc", NULL); 
dispatch_async(queue, ^{ 
    result = [self readDisc]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     //update UI or do whatever you need to do with the result of readDisc 
    }); 
}); 
dispatch_release(queue); 
+0

我想大家幾乎都同意NSOperation比GCD更可取? – xonegirlz

+1

我認爲你使用的是真實情境。如果您只想設置一個塊來執行代碼中的某一點,則Grand Central Dispatch非常好。雖然NSOperation有更多的功能,你可以在你的代碼的不同部分進行子類化和運行。 GCD只是簡化了您的情況,輕鬆獲取後臺操作的結果並將其用於主隊列中。 – RGullotti

+0

我也認爲GCD在使用iOS時更好,因爲NSOperation在使用mac進行編程時不會像使用GCD那樣使用GCD。這樣做的缺點是你可能會得到很多線程,這意味着操作系統必須保持切換。 GCD將優化並添加一個塊到現有的具有相同優先級e.t.c的隊列中,這可以節省過程能力和時間。 – geminiCoder

相關問題