0

This probably has something to do with my understanding of blocks and probably how/when the NSOperationQueue fires it's operations but I'll ask anyway:

I have a basic fetch request method:

- (void)fetchActiveUser:(NSString*)username withPassword:(NSString *)password {

    [self setAuthorizationHeaderWithUsername:username password:password];

    // SETS FLAG that we are performing a request
    fetchModeActive = TRUE;

    [self getPath:kTLActiveUserURI parameters:nil success:^(AFHTTPRequestOperation 
      *operation, id responseObject) {

    if ([responseObject isKindOfClass:[NSXMLParser class]]) {
        TLPersonParser *personParser = [[TLPersonParser alloc] 
          initWithParser:responseObject];

        [personParser setDelegate: self];
        [personParser parsePeople];

        [personParser release];

    }
    // handle stuff here.
    NSLog(@"Success!");
    fetchModeActive = FALSE;
    [[NSNotificationCenter defaultCenter] 
      postNotificationName:kTLFetchedActiveUserNotification object:nil];


    } 
    failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) {
      NSLog(@"Failure.");
      fetchModeActive = FALSE;
      [[NSNotificationCenter defaultCenter] 
        postNotificationName:kTLFetchedActiveUserNotification object:error];
    }];


    while(self.fetchModeActive) {
        // WHY DOES THIS RUN INFINITELY?
        // Both above Success: & Failure: blocks set fetchModeActive = FALSE 
        // when complete
        NSLog(@"fetching....");
    }

}

Scroll to the very bottom and you will see my waiting while loop. Why is this running infinitely outputting "fetching..." ?? Both success: and failure: blocks set our fetchModeActive flag back to false ?

My understanding was that this fetch operation runs asynchronously in the background but it looks like the fetch isn't even being performed!

Any suggestions? Do I need to fire the fetch request in a separate thread?

Thanks!

skålfyfan
  • 4,931
  • 5
  • 41
  • 59
  • the reason is you are blocking the main thread with the while loop, which is very bad – Felix Apr 19 '12 at 18:27
  • Personally I think the while loop is an "ugly" solution for your callback. Try to use the technique explained in the following post: http://stackoverflow.com/a/10233493/250164 – Wolfgang Schreurs Apr 19 '12 at 19:36

1 Answers1

1

To answer your question, the reason why this doesn't terminate is that you need a __block directive before fetchModeActive in order for the block to be able to change the variable outside the scope of the block. (You'll also want to use YES and NO as boolean literals, as they're the convention in Objective-C)

But to address a larger point, you shouldn't do it this way. Instead, create an operation, and either -start it--or better yet--add it to an NSOperationQueue. Everything will execute asynchronously in the background and trigger the callbacks when they finish.

Asynchronous programming can be difficult to get your head around. If you need to define behavior that depends on this method finishing, you may want to add a block parameter to the method, and execute that in the success and failure callbacks.

mattt
  • 19,544
  • 7
  • 73
  • 84
  • Nice to get a response from the AFNetworking man himself! Cheers. Isn't the above code _[self getPath:xxx success:^(..) failure:^(..)_ creating an NSOperation and adding the fetch to the NSOperationQueue already? Read in the AFN API that's exactly what it does. Anyhow - to achieve what I needed, it all had to do with my understanding of blocks as explained in your last paragraph. Thanks! – skålfyfan Apr 20 '12 at 19:31