0

I don't understand how Objective-C loop system works. I have function (hope names are right, rather check in code) which executes query from Health Kit. I got my mind blown when I realised that function pass return value before query finishes.

__block bool allBeckuped = true;
HKSampleQuery *mySampleQuery = [[HKSampleQuery alloc] initWithSampleType:mySampleType
                                       predicate:myPredicate
                                           limit:HKObjectQueryNoLimit
                                 sortDescriptors:@[mySortDescriptor]
                                  resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) {
                                      if(!error && results)
                                      {
                                          for(HKQuantitySample *samples in results)///main hk loop
                                          {
                                              allBeckuped = false;

                                              NSLog(@"1");
                                          }
                                      }
                                  }];//end of query

[healthStore executeQuery:mySampleQuery];
 NSLog(@"2");
return allBeckuped;

I'm trying to check if there are any new data, but I don't know where to put condition for that, because nslog2 is called before nslog 1.

Any words I should Google up?

Sam Spencer
  • 8,492
  • 12
  • 76
  • 133
Lolipop52
  • 25
  • 8
  • The query is done asynchronously in the background. That is why the return statement is reached long before the result handler is called. – rmaddy Dec 07 '15 at 20:41

1 Answers1

0

Any words I should google up?

You can start with: asynchronous design, blocks, GCD/Grand Central Dispatch should help as well - you're not using it but asynchronous designs often do.

Look at the initWithSampleType: method you are calling, it is an example of a method following the asynchronous model. Rather than return a result immediately, which is the synchronous model you are probably used to, its last argument, resultsHandler:, is a block which the method calls at some future time passing the result of its operation to it.

This is the pattern you will need to learn and follow.

Your method which contains the call to initWithSampleType: cannot return a result (e.g. your allBeckuped) synchronously. So it needs to take a "results handler" block argument, and the block you pass to initWithSampleType: should call the block passed to your method - and so the asynchronous flow of control is weaved.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86