在后台线程中运行操作并有一个完成块?

时间:2012-06-21 23:08:00

标签: iphone objective-c ios ipad

我有一个从磁盘读取的任务,可能需要花费很长时间,所以不想在主线程中执行..我想要的是在读取后调用函数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中生成的结果。如何在完成块中访问它?这几乎是不可能的吗?

2 个答案:

答案 0 :(得分:7)

使用NSInvocations可以实现超出主线程的大量工作,但远比必要复杂得多。

GCD和NSOperations都可用于实现各种并发策略。从面向对象的角度来看,NSOperations比CGD块更抽象,这使得它们(imo)更容易设计"使用,并且可能超出我实施它们的范围。 GCD是较低级别的:这使得与它的交互看起来稍微复杂一些(它实际上并不是很复杂),但是那些参与其中的人会告诉你它是更高效的"并承担更少的开销"。

我个人的方法是在我的应用程序中具有设计/协调的并发模式的场景中使用NSOperations,并使用GCD进行简单的并发/后台操作。

如果我需要做的就是解雇一些与设计无关但需要在后台完成的任意任务,我会使用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];
        })
})];

答案 1 :(得分:0)

您可以随时使用宏观中央调度来在后台执行操作。

由于它是一个块,您可以正常调用该方法并存储结果。如果您需要更新任何UI或完成后需要执行任何操作,请抓取主队列。

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);