So on my spare time I'm working on an HTTP request 'engine'. What I'm trying to build is an 'engine' that generate a request / parse response to a generic object for an iphone app.
And most of all, it should _allways_ callback the UI.
Whatever happened (NSURLRequest timeout / parsing error / NSExcept raised) (maybe SIG as well some day ?)
So I created something gory using blocks and dispatch_once. It works but I'm having this Clang warning. I mean my requests works, and in case of an exception the UI is called once apparently.
Call to 'dispatch_once' uses the local variable 'once' for the predicate value. Using such transient memory for the predicate is potentially dangerous
This is the heart of the problem
// invoke a bloc in a proper thread with a proper autorelease / trycatch / logs
static inline void api_dispatch_concurrent(EngineOnceCallback block, SEL caller, EngineCallback callback) {
dispatch_async(APIengineQueue(), ^{ // serial dispatch_queue
@autoreleasepool {
dispatch_once_t once = 0;
@try {
// block may callback using 'once'
(block) ? block(once) : NULL;
}
@catch (NSException *exception) {
[[ACLogs sharedLogs] logException:exception caller:caller
class:[ACRetroscopeEngine class]];
APILog(@"NSException invoking API block:%@", exception);
dispatch_once(&once, ^{
APILog(@"Perform callback as recover from exception");
ACResponse *defaultResponse = [ACResponse responseWithException:exception];
try_catch(block_safe_invoke_main_thread(callback, defaultResponse));
});
}
@finally {
}
}
});
}
Some macros used there :
#define block_safe_invoke(block, ...) (block != NULL) ? block(__VA_ARGS__) : NULL;
#define block_safe_invoke_main_thread(block, ...) \
if ([NSThread isMainThread]) { \
block_safe_invoke(block, __VA_ARGS__) \
} else { \
dispatch_sync(dispatch_get_main_queue(), ^{ \
block_safe_invoke(block, __VA_ARGS__) \
}); \
} \
Thanks in advance :p