1

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

4

2 回答 2

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];
        })
})];
于 2012-06-22T00:40:04.453 回答
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);
于 2012-06-21T23:24:20.597 回答