Kis*_*dan 7 objective-c grand-central-dispatch getter-setter ios
我已经过度使用了一个请求在线服务获取结果的getter.如何强制getter仅从同步块返回结果?
@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
Run Code Online (Sandbox Code Playgroud)
有一个非常好的谷歌搜索至少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;
}
Run Code Online (Sandbox Code Playgroud)
如果您从异步线程调用此方法,它不会阻塞 UI,但如果您从主队列/线程调用它,那么它将阻塞 UI,因为您正在主线程上等待信号量。不管你如何实现等待,它总是会阻塞UI,因为主线程是一个串行队列。这意味着在异步块完成之前,主队列上的其他块或事件都不会运行。
如果您不想阻塞 UI,则不要调用任何可能阻塞主线程的内容。一个好的模式是使用 @Collin 建议的完成块。模式如下:
- (void) computeAnyncValueWithCompletionBlock:((void)^(double value))completionBlock
{
dispatch_async(not_the_main_queue, ^(void) {
// do some expensive computation.
double value = 3.1415926535;
completionBlock(value);
});
}
Run Code Online (Sandbox Code Playgroud)
这可以从任何地方调用并且永远不会阻塞。
| 归档时间: |
|
| 查看次数: |
3174 次 |
| 最近记录: |