我正在开发一款允许用户通过iPad在云端创建文件和文件夹的应用。
删除文件后,应用程序会自动在云上创建“回收站”文件夹并将该文件放入其中。我为所有操作创建了NSOperationQueue
,即我有单独的文件夹创建队列和单独的文件上载队列。我面临的问题是,文件上传操作在文件夹创建操作完成之前执行,因此文件无法成功上传。
有人可以帮我把文件夹创建操作同步吗?
我尝试过以下代码
[create_folder_queue addOperations:[NSArray arrayWithObject:folderOperation] waitUntilFinished:YES];
但它不执行操作。
提前致谢。
答案 0 :(得分:12)
如果需要同步队列,请在操作队列上运行-setMaxConcurrentOperationCount:
方法将其设置为1
。
设置此属性后,队列中一次最多只能运行一个操作,这或多或少是同步队列的定义,其中一个任务仅在另一个任务完成后才会执行。
答案 1 :(得分:4)
据我所知,一个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];
注意本例中没有内存管理。
答案 2 :(得分:1)
这可以解决您的问题:
[create_folder_queue addOperation:folderOperation];
[create_folder_queue waitUntilAllOperationsAreFinished];
// ... now start file upload ...
答案 3 :(得分:1)
与setMaxConcurrentOperationCount
一起,在NSOperation
子类中
:
- (void)main
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool release];
}
- (BOOL)isConcurrent {
return FALSE;
}
现在它处于完全串行序列模式。
答案 4 :(得分:1)
您可能不应该使用单独的操作队列。由于这些都是云文件操作,因此您应该有一个云文件操作队列执行所有云文件操作。
如果这些操作不依赖于其他操作,则只需将它们添加到此队列中,即可按照系统认为有用的任何顺序执行这些操作,并且可以同时执行这些操作。当然,如果您认为这是个好主意,则可以设置maxConcurrentOperationCount
来对此设置自己的限制,但是不必这样做,在这种情况下,系统将为您做出决定。
如果操作确实相互依赖,请使用操作依赖系统。因此,您首先创建操作,然后使用addDependency
告诉系统哪个操作取决于哪个其他操作。如果现在将所有这些操作添加到队列中,系统将确保以正确的顺序运行它们,以便某个操作仅在其所依赖的所有操作完成后才能运行(并且这些操作可能再次取决于其他操作,因此上)。只要确保不创建循环依赖项(OpA依赖于OpB,OpC依赖于OpC,OpA依赖于OpA),然后它们中的任何一个都不会运行。
但是通常要回答这个问题,以防其他用户问到如何用dispatch_sync
模拟NSOperationQueue
:
NSOperationQueue * queue = ...;
NSOperation * someOperation = [NSBlockOperation
blockOperationWithBlock:^{
// ... do whatever you want to do ...
}
];
[queue addOperation:someOperation];
[someOperation waitUntilFinished];
但是请注意,这比在串行调度队列上调用dispatch_sync
的性能要差得多,因为上面的代码总是会导致两个线程切换,而在串行调度队列上调用dispatch_sync
则会将调用线程重用到运行该块,因此根本不会发生线程切换,该过程也不需要第二个线程来执行。 See here,详细了解其工作原理。
答案 5 :(得分:0)
为什么你有两个队列?如果您只有一个,那么您的问题就会被依赖项解决(请参阅documentation)。