我是异步回调的新手,并且给出了不同的建议。我需要执行异步回调,经过几个小时的研究后,我仍然不知道是否应该使用块或GCD和队列。任何指针都会受到欢迎。
行。所以我真正要问的是:
"为了使用'异步'回调,我需要使用GCD和队列吗?"
我从答案中收集的是答案是是。 块内绝对 GCD 和队列。
我的困惑源于这样一个事实:我得到的方向是我所需要的只是一个块,如下面的代码:
[UIView animateWithDuration:.4f
animations:^{
flashView.alpha = 0.f;
}
completion:^(BOOL finished){
[flashView removeFromSuperview];
}
];
但我在答案中看到的是,上述方块不足以使异步&#39;回调。相反,我 DO 实际上需要在块中使用 GCD 和队列,如下面的代码:< / p>
- (void)invokeAsync:(id (^)(void))asyncBlock resultBlock:(void (^)(id))resultBlock errorBlock:(void (^)(id))errorBlock {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id result = nil;
id error = nil;
@try {
result = asyncBlock();
} @catch (NSException *exception) {
NSLog(@"caught exception: %@", exception);
error = exception;
}
// tell the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSAutoreleasePool *secondaryPool = [[NSAutoreleasePool alloc] init];
if (error != nil) {
errorBlock(error);
} else {
resultBlock(result);
}
[secondaryPool release];
});
[pool release];
});
}
答案 0 :(得分:3)
异步回调是指当前线程继续执行语句,并在不同的线程中分离执行代码以便以后运行的。
有几种技术可以实现这一目标。在这个例子中,我用4种不同的异步方式调用方法cacheImage:,带参数图像(只是一个例子)。
// 1. NSThread
[NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:self withObject:image];
// 2. performSelector...
[self performSelectorInBackground:@selector(cacheImage:) withObject:image];
// 3. NSOperationQueue
NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cacheImage:) object:image];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:invOperation];
// 4. GCD
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self cacheImage:image];
});
到目前为止,更简单的方法是使用GCD,因为它已经有一个可供您使用的线程,而不必自己使用其他选项创建它。
但是,因为块是作为对象实现的,所以你确实可以使用没有GCD的块,例如:
// block definition
typedef void (^hello_t)();
// method that uses a block as parameter
-(void) runBlock:(hello_t)hello {
hello();
}
// asynchronous execution of a block
[NSThread detachNewThreadSelector:@selector(runBlock) toTarget:self withObject:^(){
NSLog(@"hi");
}];
PS:您不需要手动使用NSAutoreleasePool,除非您创建了许多对象并且您想立即释放内存。此外,@ try @catch很少用于Objective-C
答案 1 :(得分:2)
这里没有任何混淆点。 GCD也有块执行。 GCD API,支持在系统的Unix级别上异步执行操作。
块对象是C级语法和运行时功能。它们类似于标准C函数,但除了可执行代码之外,它们还可能包含对自动(堆栈)或托管(堆)内存的变量绑定。因此,块可以维护一组状态(数据),以便在执行时可以用来影响行为。
Apple设计的块的明确目标是为Grand Central Dispatch线程体系结构编写程序更容易,尽管它独立于该体系结构,并且可以像其他语言中的闭包一样使用。 Apple已经在他们自己的GNU Compiler Collection分支和Clang LLVM编译器前端中实现了块。语言运行时库对块的支持也可作为LLVM项目的一部分。因此,在相同功能的情况下,您可以使用其中任何一个。