且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

NSOperation和NSOperationQueue工作线程vs主线程

更新时间:2023-02-09 17:10:02


我的问题是数据库写操作是在主
线程还是后台线程中发生的?

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

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

If you create an NSOperationQueue from scratch as in:

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

它将在后台线程中:

操作队列通常提供用于运行
操作的线程。在OS X v10.6及更高版本中,操作队列使用
libdispatch库(也称为Grand Central Dispatch)来启动
执行其操作。 因此,操作总是在单独的线程上执行
,无论它们是否被指定为并发或非并发操作的

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

您还可以看到如下代码:

You can also see code like this:

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 可以更好地控制你想要的东西去做。您可以在两个操作之间创建依赖关系(下载并保存到数据库)。要在一个块和另一个块之间传递数据,您可以假设,例如, NSData 将来自服务器,因此:

NSOperationQueue gives finer control with what you want to do. You can create dependencies between the two operations (download and save to database). To pass the data between one block and the other, you can assume for example, that a NSData will be coming from the server so:

__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];

编辑:为什么我使用 __弱操作参考,可以在这里找到。但简而言之就是避免保留周期。

Why I am using __weak reference for the Operations, can be found here. But in a nutshell is to avoid retain cycles.