ios - NSOperation 和 NSOperationQueue 工作线程与主线程

我必须在我的应用程序中执行一系列下载和数据库写入操作。我正在使用 NSOperationNSOperationQueue

这是应用场景:

  • 获取某个地点的所有邮政编码。
  • 为每个邮政编码获取所有房屋。
  • 为每所房子获取居民详细信息

如前所述,我为每个任务定义了一个 NSOperation。在第一种情况下(Task1),我向服务器发送请求以获取所有邮政编码。 NSOperation 中的委托(delegate)将接收数据。然后将此数据写入数据库。数据库操作在不同的类中定义。从 NSOperation 类中,我正在调用数据库类中定义的写入函数。

我的问题是数据库写操作是发生在主线程还是后台线程?当我在 NSOperation 中调用它时,我希望它与 NSOperation 一样在不同的线程(不是 MainThread)中运行。有人可以在处理 NSOperationNSOperationQueue 时解释这种情况。

最佳答案

My question is whether the database write operation occur in main thread or in a background thread?

如果您从头开始创建 NSOperationQueue,如下所示:

NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];

它将在后台线程中:

Operation queues usually provide the threads used to run their operations. In OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central Dispatch) to initiate the execution of their operations. As a result, operations are always executed on a separate thread, regardless of whether they are designated as concurrent or non-concurrent operations

除非你使用 mainQueue:

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];

你也可以看到这样的代码:

NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperationWithBlock:^{

   // Background work

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // Main thread work (UI usually)
    }];
}];

还有 GCD 版本:

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
             {
              // Background work            
             dispatch_async(dispatch_get_main_queue(), ^(void)
              {
                   // Main thread work (UI usually)                          
              });
});

NSOperationQueue 可以更好地控制您想要做什么。您可以在两个操作之间创建依赖关系(下载并保存到数据库)。例如,要在一个 block 和另一个 block 之间传递数据,您可以假设 NSData 将来自服务器,因此:

__block NSData *dataFromServer = nil;
NSBlockOperation *downloadOperation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakDownloadOperation = downloadOperation;

[weakDownloadOperation addExecutionBlock:^{
 // Download your stuff  
 // Finally put it on the right place: 
 dataFromServer = ....
 }];

NSBlockOperation *saveToDataBaseOperation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakSaveToDataBaseOperation = saveToDataBaseOperation;

 [weakSaveToDataBaseOperation addExecutionBlock:^{
 // Work with your NSData instance
 // Save your stuff
 }];

[saveToDataBaseOperation addDependency:downloadOperation];

[myQueue addOperation:saveToDataBaseOperation];
[myQueue addOperation:downloadOperation];

编辑: 为什么我使用 __weak 引用进行操作,可以找到 here .但简而言之就是避免保留循环。

https://stackoverflow.com/questions/19569244/

相关文章:

ios - 没有为应用商店上的应用程序找到有效的 'aps-environment' 权利字符串

iphone - 如何找到 malloc "double free"错误的原因?

ios - 如何使用 UISegmentedControl 切换 View ?

iphone - NSTimeInterval 到 HH :mm:ss?

objective-c - Objective-C中的ivars和属性有什么区别

objective-c - ARC : strong or retain? 的@property 定

ios - 为什么masksToBounds = YES会阻止CALayer阴影?

objective-c - 如何向 objc_exception_throw 添加断点?

objective-c - .h 和 .m 文件中的@interface 定义之间的区别

iphone - 如何为 View 或图像沿弯曲路径的移动设置动画?