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!
To answer your question, the reason why this doesn’t terminate is that you need a
__blockdirective beforefetchModeActivein order for the block to be able to change the variable outside the scope of the block. (You’ll also want to useYESandNOas 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
-startit–or better yet–add it to anNSOperationQueue. 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.