我已经覆盖了一个请求在线服务以获得结果的 getter。 如何强制 getter 仅从同步块(synchronized block)返回结果?
@interface MyClass ()
@property (nonatomic, strong) NSMutableDictionary* myDictionary;
@end
@implementation MyClass
-(NSMutableDictionary*) myDictionary {
dispatch_async(queue, ^{
/* perform online request */
dispatch_sync(dispatch_get_main_queue(), ^{
// I need to obtain lock until this line gets executed and only then return
});
});
}
@end
通过谷歌搜索至少 3 小时,我遇到了 dispatch_group_async、dispatch_semaphore 和 __block。我不知道我是否用错了它们但没有达到目的。
更新 1:
myDictionary
是一个异步属性。我想看看这是否可以通过 getter 本身来实现。
最佳答案
@Kishor 当请求真正异步时,UI 不会阻塞。您的“异步”请求阻止 UI 的原因是,实际上它们不是异步的。以下是伪代码中的原因:
- (double) notTruelyAsyncValue
{
__block double someExpensiveDoubleToCompute = 0.0;
// One of the many ways that we can coordinate concurrent threads.
dispatch_semaphore_t sema_done = dispatch_semaphore_create(0);
dispatch_async(not_the_main_queue, ^(void) {
// Simulate long processing time.
sleep(5);
someExpensiveDoubleToCompute = 3.1415926535;
dispatch_semaphore_signal(sema_done);
});
// We can't return until the async block has returned.
// So we wait until it's done. If we wait on the main queue
// then our UI will be "frozen".
dispatch_semaphore_wait(sema_done, DISPATCH_TIME_FOREVER);
// Now we have our result we free the resources and return
dispatch_release(sema_done);
return someExpensiveDoubleToCompute;
}
如果您从异步线程调用此方法,它不会阻塞 UI,但如果您从主队列/线程调用它,那么它会阻塞 UI,因为您正在等待主线程上的信号量。不管你如何实现你的等待,它总是 阻塞 UI,因为主线程是一个串行队列。这意味着在您的异步 block 完成之前,主队列上的其他 block 或事件不会运行。
如果您不想阻塞您的 UI,那么不要调用任何可能阻塞主线程的东西。一个好的模式是按照@Collin 的建议使用完成 block 。模式如下:
- (void) computeAnyncValueWithCompletionBlock:((void)^(double value))completionBlock
{
dispatch_async(not_the_main_queue, ^(void) {
// do some expensive computation.
double value = 3.1415926535;
completionBlock(value);
});
}
这可以从任何地方调用并且永远不会阻塞。
关于ios - 如何从异步属性的 getter 返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15805086/