iphone - NSOperationQueue and ASIHTTPRequest -


i'm writing test cases wrapper class written around asihttprequest. reasons can't determine, test cases complete failure before asihttprequest finishes.

here's how program flow works.

  1. start in test case.
  2. init http engine object, instruct create new list
  3. create new asihttprequest object , set up.
  4. add request operation queue.
  5. wait until queue empty
  6. check see if delegate methods called , fail test if weren't.

now, of time works fine , test passes, of time fails because delegate methods called after operation queue returned control wait method.

test case

// set flags 'no' - (void)setup {     requestdidfinish = no;     requestdidfail = no; }  - (void)testcreatelist {     nsstring *testlist = @"{\"title\": \"this list\"}";      jkengine *engine = [[jkengine alloc] initwithdelegate:self];     nsstring *requestidentifier = [engine createlist:jsonstring];      [self waituntilenginedone:engine];     nsstring *responsestring = responsestring_;     [engine release];      ghassertnotnil(requestidentifier, nil);     ghasserttrue(requestdidfinish, nil);     ghasserttrue([responsestring hasprefix:@"{\"createoreditlistresult\""], nil);  }  // puts test holding pattern until http request done - (void)waituntilenginedone:(jkengine *)engine {     [engine waituntilfinishedrunning];  }  // delegate method called on successful completion - (void)requestfinished:(nsstring *)requestidentifier withresponse:(nsstring *)response {     nslog(@"request did finish");     requestdidfinish = yes;     responseidentifier_ = [requestidentifier retain];     responsestring_ = [response retain]; } 

engine code

- (nsstring *)createlist:(nsstring *)list {     asihttprequest *request = [[asihttprequest alloc] initwithurl:[nsurl urlwithstring:url]];     [request addrequestheader:@"content-type" value:kcontenttype];     [request setrequestmethod:kpost];     request.delegate = self;      [request appendpostdata:[list datausingencoding:nsutf8stringencoding]];      nsstring *requestidentifier = [nsstring stringwithnewuuid];      [operationqueue_ addoperation:request];     [operationdictionary_ setobject:request forkey:requestidentifier];      return requestidentifier; }  // asihttprequest delegate method that's called on success //   isn't called until after operationqueue finishes running - (void)requestfinished:(asihttprequest *)request {     dlog([request responsestring]);      bool cannotifiydelegate = [self.delegate respondstoselector:@selector(requestfinished:withresponse:)];     if (cannotifiydelegate) {         nsarray *keyarray = [operationdictionary_ allkeysforobject:request];         nsstring *requestidentifier = [keyarray objectatindex:0];         [operationdictionary_ removeobjectforkey:requestidentifier];          if ([keyarray count] != 1) {             alog(@"it looks request added operation dictionary multiple times. there's bug somewhere.", nil);         }          [self.delegate requestfinished:requestidentifier withresponse:[request responsestring]];     } }  - (void)waituntilfinishedrunning {     [operationqueue_ waituntilalloperationsarefinished]; } 

this way asihttprequest works. delegate methods called on main thread, , calls delegates not block request thread, it's possible delegates called after queue finishes.


Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -