Kappe
Kappe

Reputation: 9505

AFNetworking automatically dispatch completion block in caller's thread

I'm using AFNetworking with custom NSOperations and Core data, the Core Data concurrency is well managed and the NSOperation uses a proper Managed object context, something like: (is an abstraction)

// MO created in context A
NSManagedObject * foo = ...;
__Block NSManagedObjectID * fooId = foo.objectID;

NMBlockOperation * customOp = [[NMBlockOperation alloc] initWithBlock:^(NMOperation *operation) {

// MO created in context B   
NSManagedObject * safeFoo = [[operation.coreDataManager mocForCurrentThread] objectWithID: fooId];         
...

[_networkManager POST:[self apiUrlStringForPath: xxx]
                   parameters:parameters
                      success:^(AFHTTPRequestOperation *operation, id responseObject) {

                      //Do something with the foo object

                      // MO created in context C   
                      NSManagedObject * safeFoo = [[operation.coreDataManager mocForCurrentThread] objectWithID: fooId];     
[operation finish];
                      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    [operation fail];
                      }];        
        }];

... add customOp to a queue

I'm forced to pass the Managed object from context to context due the fact that the context A, B and C are created in different threads, Is possible force the AFNetworking call to execute the failure/success blocks in the caller's thread? Using this approach I could be able to pass the Managed objects only from context A to the NSOperation's context B.

I know how to set the network manager completion queue but this doesn't help me, I want the same caller's thread.

//configure standard network manager
_networkManager = [[AFHTTPRequestOperationManager alloc] init];
//Configure completation queue
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.xxx.afnetComplQueue", NULL);
_networkManager.completionQueue = backgroundQueue;

Upvotes: 1

Views: 1360

Answers (1)

Aaron
Aaron

Reputation: 615

AFNetworking executes the callback blocks on the main queue, as indicated by the answer to this question:

Are AFNetworking success/failure blocks invoked on the main thread?

If you are using GCD you aren't working with "threads" but instead with queues. The "thread" for the block operation will die once it has been completed, so when the callback is executed it will be impossible to have it be called in the same thread because it no longer exists. It is a bit unclear to me exactly what you are trying to achieve, but the answer to your question is no, you wan't be able to have the callback block execute on the same "thread".

I use quotes around thread to indicate that I mean it in the literal sense as it relates to the OS.

EDIT

It seems that the answer on the other SO question is no longer valid. Checking the source code, the completion blocks for an AFHTTPRequestOperation are executed on a concurrent queue. This is the relevant portion of the source:

https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPRequestOperation.m#L107

Upvotes: 2

Related Questions