簡體   English   中英

使NSOperation同步

[英]Make NSOperation synchronous

我正在開發一個應用程序,允許用戶從iPad上創建雲上的文件和文件夾。 刪除文件后,應用程序會自動在雲上創建“回收站”文件夾並將該文件放入其中。 我為所有操作創建了NSOperationQueue ,即我有單獨的文件夾創建隊列和文件上傳的單獨隊列。 我面臨的問題是,文件上傳操作在文件夾創建操作完成之前執行,因此文件無法成功上傳。

任何人都可以幫助我使文件夾創建操作同步嗎?

我試過以下代碼

[create_folder_queue addOperations:[NSArray arrayWithObject:folderOperation] waitUntilFinished:YES];

但它不執行操作。

提前致謝。

如果需要同步隊列,請在操作隊列上運行-setMaxConcurrentOperationCount:方法將其設置為1

設置此屬性后,隊列中一次最多只能運行一個操作,這或多或少是同步隊列的定義,其中一個任務僅在另一個任務完成后才會執行。

據我所知,一個NSOperation對象可以依賴於其他對象,並且它們不必在同一個操作隊列中執行。 所以你可以做下一個:

// create queues
NSOperationQueue *folder_creation_queue = [[NSOperationQueue alloc] init];
NSOperationQueue *file_uploading_queue  = [[NSOperationQueue alloc] init];
// create operations
NSInvocationOperation *folder_creation_operation = [[NSInvocationOperation alloc] 
                                                     initWithTarget:aFolderTarget 
                                                     selector:@selector(folderCreation) 
                                                     object:aFolderObject];
NSInvocationOperation *file_uploading_operation = [[NSInvocationOperation alloc] 
                                                     initWithTarget:aFileTarget 
                                                     selector:@selector(fileUpload) 
                                                     object:aFileObject];
// Set dependency for the folder_uploading_operation. 
// It prevents this operation begin executing before 
// folder_creation_operation finished.
[file_uploading_operation addDependency:folder_creation_operation];
// Execute these operations
[folder_creation_queue addOperation:folder_creation_operation];
[file_uploading_queue addOperation:file_uploading_operation];

請注意,此示例中沒有內存管理。

您可能不應該使用單獨的操作隊列。 由於這些都是雲文件操作,因此您應該有一個雲文件操作隊列來執行所有雲文件操作。

如果操作不依賴於其他操作,則只需將它們添加到此隊列中,它們將按任何順序執行,並且在系統認為有用的同時執行它們中的許多操作。 當然,你可以設置maxConcurrentOperationCount來設置你自己的限制,如果你認為這是一個好主意,但你不必,在這種情況下系統會為你決定。

如果操作確實相互依賴,則使用操作依賴性系統。 因此,您首先創建操作,然后使用addDependency告訴系統哪個操作取決於哪個操作。 如果您現在將所有這些操作添加到隊列中,系統將確保以正確的順序運行它們,以便操作僅在其依賴的所有操作完成后運行(並且這些操作可能再次依賴於其他操作,因此上)。 只是確保不創建循環依賴(OpA依賴於依賴OpC的OpB,這取決於OpA),因為它們都不會運行。

但是對於一般的問題答案,以防其他用戶詢問如何使用NSOperationQueue模擬dispatch_sync

NSOperationQueue * queue = ...;
NSOperation * someOperation = [NSBlockOperation
    blockOperationWithBlock:^{
        // ... do whatever you want to do ...
    }
];
[queue addOperation:someOperation];
[someOperation waitUntilFinished];

但請注意,這比在串行調度隊列上調用dispatch_sync要低得多,因為上面的代碼總是會導致兩個線程切換,而在串行調度隊列上調用dispatch_sync將重用調用線程來運行塊,因此根本不會有線程切換發生,這個過程也不需要第二個線程這樣做。 有關其工作原理的詳細信息, 請參見此處

這應該可以解決您的問題:

[create_folder_queue addOperation:folderOperation];
[create_folder_queue waitUntilAllOperationsAreFinished];

// ... now start file upload ...

setMaxConcurrentOperationCount ,在您的NSOperation子類中:

- (void)main
{    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [pool release];
}

- (BOOL)isConcurrent {
    return FALSE;
}

現在它處於完全串行序列模式。

你為什么有兩個隊列? 如果只能有一個,那么您的問題就會被依賴項解決(請參閱文檔 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM