ios - 必须在另一个线程中使用 dispatch_semaphore_t 吗?
问题描述
这是一个数组的延迟加载:
@property (nonatomic, strong) NSArray *dataArray;
- (NSArray *)dataArray {
if (!_dataArray) {
// if array is nil,load data
dispatch_semaphore_t signal = dispatch_semaphore_create(0);
[DataManager loadListSuccess:^(NSArray * _Nonnull list) {
self->_dataArray = list;
dispatch_semaphore_signal(signal);
} failure:^{
dispatch_semaphore_signal(signal);
}];
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
return _dataArray;
} else {
return _dataArray;
}
}
我想要的是在调用getter方法时dataArray
,检查是否为nil。如果为nil,则加载数据,然后返回。如果不是,直接返回。
下面是加载数据的代码:
+ (void)loadListSuccess:(void (^)(NSArray *list))success failure:(dispatch_block_t)failure {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
success(@[@"1", @"2", @"3"]);
});
}
在 viewDidLoad 中:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(@"viewDidLoad");
NSLog(@"self.dataArray ===== %@", self.dataArray);
NSLog(@"load finish");
}
控制台仅打印viewDidLoad 。并且所有 userInteractionEnabled 都被禁用。
但是,如果我将加载数据方法更改为:
+ (void)loadListSuccess:(void (^)(NSArray *list))success failure:(dispatch_block_t)failure {
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),queue, ^{
success(@[@"1", @"2", @"3"]);
});
}
控制台打印:
- viewDidLoad
- self.dataArray ===== ( 1, 2, 3 )
- 加载完成
另外,这是我所期望的。
困扰我的是为什么在主线程中它不起作用?是否有死锁?
解决方案
有没有死锁
对,就是这样。尽管您使用的dispatch_after
是异步的,但您对信号量的使用破坏了异步性,这意味着您正在有效地尝试从主线程同步重新进入主线程。你不能那样做。
推荐阅读
- nestjs - Nest js 打包挂在无服务器框架的构建过程中
- react-native-render-html - 不尊重 fontSize 的元素
- python - 如何重新启动使用套接字的 python 程序?
- emacs - 组织模式 | 如何将一列与另一列相乘并对结果求和?
- stm32 - STM32F4通过UART写内部flash
- python - 图像和帖子仅适用于 Django Admin 而不是常规形式
- javascript - 如果所有这些都以角度传递,数组任务如何
- entity-framework - 使用 Entity Framework Core 和 .net core 3.1 进行自引用连接
- android - Xamarin.Android:使用 R8 或 dotfuscator 发布构建正常,但不能同时使用两者
- python - django: filter.values(...) 不检索请求的字段