Your method getLuminosity
invokes an asynchronous method. This inevitable makes the calling method asynchronous as well!
So, the first step to a working approach is to realize that your method getLuminosity
is asynchronous, and an asynchronous method SHOULD provide a means to signal the call-site that the underlying asynchronous task is complete:
We might use a "completion handler" to accomplish this, but keep in mind that this is not the only way to achieve this (see @b52 answer how to accomplish this with promises).
The completion handler - a Block to be more precise - needs to be defined (that is, implemented) by the call-site. When the call-site "starts" the asynchronous task (through invoking the asynchronous method) the completion handler gets passed through to the asynchronous task. The task's responsibility is to "call" the completion handler when it is finished.
Usually, the completion handler has parameters which will be used to transfer the result of the asynchronous task. For example, we could define a completion block as follows:
typedef void (^completion_t)(NSNumber* averageLumin, NSError* error);
Note: usually, the "type" of the completion handler will be defined by the underlying asynchronous task, respectively its requirements. The implementation of the block, though, will be provided by the call-site.
Your asynchronous method can then look like this:
- (void) luminosityWithCompletion:(completion_t)completion;
And can be implemented:
- (void) luminosityWithCompletion:(completion_t)completion
{
...
[vidCam startCameraCapture];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[vidCam stopCameraCapture];
NSNumber *averageLumin = [_arrayOfLumins valueForKeyPath:@"@avg.self"];
if (completion) {
completion(averageLumin, nil)
}
});
On the call-site, you use a "continuation" to do whatever is necessary when the result is eventually available:
- (void) foo
{
...
// Define the "continuation" with providing the completion block:
// Put *everything* that shall be executed *after* the result is
// available into the completion handler:
[self luminosityWithCompletion:^(NSNumber* result, NSError*error) {
if (error) {
// handle error
}
else {
// continue on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
// using "result" on the main thread
float lum = [result floatValue];
...
});
}
}];
}