[英]Execute cross thread function one by one
I have some special functions in my project, they will execute cross many threads, such as childContext perform block or AFNetwork response block: 我的项目中有一些特殊功能,它们将跨许多线程执行,例如childContext perform块或AFNetwork响应块:
(void)my_function {
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
childContext.parentContext = self.managedObjectContext;
[childContext performBlock:^{
[self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
//Do something
[childContext performBlock:^{
//Do something
}];
}];
}];
});
}
Now I want to execute them one by one (including all blocks in function). 现在,我要一个一个地执行它们(包括函数中的所有块)。 After reading a couple of other answers, some of the Apple documentation, I get some answers:
在阅读了一些其他答案,一些Apple文档后,我得到了一些答案:
I can add NSRecursiveLock for each function, but the issue is that I can't lock/unlock cross thread. 我可以为每个函数添加NSRecursiveLock,但问题是我无法锁定/解锁交叉线程。
(void)my_function {
[MyLock lock]; // Lock here
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
childContext.parentContext = self.managedObjectContext;
[childContext performBlock:^{
[self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
//Do something
[childContext performBlock:^{
//Do something
[MyLock unlock]; //Unlock here
}];
}];
}];
});
}
I can add each function to NSOperationQueue as a NSOperation, and set concurrent operation number to 1, but the issue is that I can't make sure the code in block has been executed even the NSOperation finishes successfully. 我可以将每个函数作为NSOperation添加到NSOperationQueue中,并将并发操作号设置为1,但是问题是,即使NSOperation成功完成,我也无法确保块中的代码已经执行。
I can add @synchronized, but has same issue as NSOperation 我可以添加@synchronized,但与NSOperation有相同的问题
My suggestion is using NSOperationQueue
and Asynchronous NSOperation
. 我的建议是使用
NSOperationQueue
和Asynchronous NSOperation
。
You can make sure operation execute one by one in two ways 您可以确保操作以两种方式一一执行
addDependency:
maxConcurrentOperationCount
to 1 maxConcurrentOperationCount
设置为1 With Asynchronous NSOperation
,it is you to decide when this Operation is done. 使用
Asynchronous NSOperation
,您可以决定何时完成此操作。
For example 例如
-(void)my_function {
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
childContext.parentContext = self.managedObjectContext;
[childContext performBlock:^{
[self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
//Do something
[childContext performBlock:^{
//Do something
//Only mark this NSOperation is done when all task of this function is finished.
}];
}];
}];
});
}
How to make an Asynchronous NSOperation
,This is what I usually do,you can also refer it in the document. 如何进行
Asynchronous NSOperation
,这是我通常要做的,您也可以在文档中参考它。
Keep two property 保留两个财产
@interface AsyncOperation (){ BOOL finished; BOOL executing; }
Use these two property to manage Operation state 使用这两个属性来管理操作状态
-(BOOL)isFinished{ return finished; } -(BOOL)isExecuting{ return executing; }
3.Mark Operation
start 3.标记
Operation
开始
Note:start function is called on the thread the Operation created 注意:在创建的线程上调用start函数
-(void)start{
if ([self isCancelled])
{
// Must move the operation to the finished state if it is canceled.
[self willChangeValueForKey:@"isFinished"];
finished = NO;
[self didChangeValueForKey:@"isFinished"];
return;
}
// If the operation is not canceled, begin executing the task.
[self willChangeValueForKey:@"isExecuting"];
[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
executing = YES;
[self didChangeValueForKey:@"isExecuting"];
}
I use this function 我用这个功能
-(void)setOperationFinished{
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
executing = NO;
finished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.