如何从异步属性的获取器返回? [英] How do I return from a getter of an asynchronous property?

查看:75
本文介绍了如何从异步属性的获取器返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经重写了要求在线服务获取结果的getter方法. 如何强制吸气剂仅从同步块返回结果?

I have over-ridden a getter that requests an online service to get a result. How do I force the getter to return the result only from synchronous 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 .我不知道我是否在错误地使用它们,但没有达到目的.

With a pretty good googling for at least 3 hrs I came across dispatch_group_async, dispatch_semaphore and __block. I don't know if I was using them wrong but didn't serve the purpose.

更新1:

myDictionary是异步属性.我想看看是否可以通过getter本身来实现.

myDictionary is an asynchronous property. I want to see if this can be implemented via the getter itself.

推荐答案

@Kishor当请求真正是异步的时,UI不会阻塞.您的异步"请求阻止UI的原因是,实际上它们不是异步的.这就是使用伪代码的原因:

@Kishor When a request is truely asynchronous the UI does not block. The reason your "asynchronous" request block the UI is that, in fact they are not asychronous. Here is why in pseudo code:

- (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.这意味着在异步块完成之前,主队列上的其他块或事件都不会运行.

If you call this method from an asynchronous thread it will not block the UI but if you call it from the main queue/thread then it WILL block the UI because you are waiting on a semaphore on the main thread. Regardless of how you implement your waiting, it will always block the UI because the main thread is a serial queue. That means no other block or event on the main queue will run until your asynchronous block is completed.

如果您不想阻止您的UI,请不要调用任何可能从主线程阻止的内容.一个很好的模式是使用@Collin建议的完成块.模式如下:

If you don't want to block your UI then don't call anything that might block from the main thread. A good pattern for this is to use completion blocks as suggested by @Collin. The pattern is as follows:

- (void) computeAnyncValueWithCompletionBlock:((void)^(double value))completionBlock 
{
     dispatch_async(not_the_main_queue, ^(void) {
          // do some expensive computation.
          double value = 3.1415926535;
          completionBlock(value);
     });
}

可以在任何地方调用它,并且永远不会阻塞.

This can be called from anywhere and will never block.

这篇关于如何从异步属性的获取器返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆