我有一个单例对象,它在后台线程上执行网络请求(通过NSOperationQueue
创建)。这很好用。网络请求发生时不会堵塞用户界面。
单身人士需要在后台网络请求期间拨打[UIApplication sharedApplication]
。此调用检索有关应用程序状态的信息。 UIKit返回的值决定了应用程序的进展方式。当然,UIKit不是线程安全的,只能从主线程调用。因此,需要在主线程上完成对app状态信息的请求。
问题是这个包含app状态信息的变量是在主线程上设置的,但是需要在不同的线程上访问。 处理此问题的最佳方式是什么?
此解决方案导致编译器错误。无法在块内修改appStateIsInForeground
。
// Create variable on separate background thread
// Configure the server connection based on the current app state
BOOL appStateIsInForeground = YES;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) appStateIsInForeground = YES;
else appStateIsInForeground = NO;
}];
// Access appStateIsInForeground variable from the same separate background thread
添加__block
说明符会使编译器错误无效。但是,我觉得这个解决方案可能会导致竞争条件或抛出异常,因为尝试访问多个线程上的变量。
// Create variable on separate background thread
// Configure the server connection based on the current app state
__block BOOL appStateIsInForeground = YES;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) appStateIsInForeground = YES;
else appStateIsInForeground = NO;
}];
// Access appStateIsInForeground variable from the same separate background thread
如何在后台线程上创建变量(使用NSOperationQueue
初始化),在主线程上为其赋值,然后在原始后台线程上读取其值,而不会产生竞争条件或导致线程安全异常?
编辑:虽然在非主线程上读取来自UIKit的值可能是安全的,但这个问题可能仍有更广泛的应用。
答案 0 :(得分:1)
我并不是百分之百确定在后台线程上只读取UIKit的值是个坏主意,但是如果它确实如此,那么使用好的dispatch_sync
可能是合理的。功能
__block BOOL appStateIsInForeground = YES;
dispatch_sync(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) appStateIsInForeground = YES;
else appStateIsInForeground = NO;
});