所以在我的业余时间,我正在研究一个 HTTP 请求“引擎”。我正在尝试构建的是一个“引擎”,它为 iphone 应用程序生成对通用对象的请求/解析响应。
最重要的是,它应该_allways _ 回调 UI。
不管发生了什么(NSURLRequest 超时/解析错误/ NSExcept 引发)(也许有一天也有 SIG?)
所以我用blocks和dispatch_once创造了一些血腥的东西。它有效,但我有这个 Clang 警告。我的意思是我的请求有效,如果出现异常,显然会调用一次 UI。
调用“dispatch_once”使用局部变量“once”作为谓词值。对谓词使用这种瞬态记忆是有潜在危险的
这是问题的核心
// 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 {
}
}
});
}
那里使用了一些宏:
#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__) \
}); \
} \
提前感谢:p