[ios]从异步属性 getter 如何返回?

标签: ios Objective-C
发布时间: 2017/3/21 23:05:44
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我过度骑过请在线的服务,以获得结果的 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

与不错谷歌搜索至少 3 小时遇到了dispatch_group_asyncdispatch_semaphore__block。我不知道是否我在利用他们错了,但没有达到目的。

更新 1:

myDictionary是一个异步的属性。我想看看是否这可以实现通过 getter 本身。

解决方法 1:

@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 然后不要叫什么可能会阻止从主线程。这一良好模式是按照 @Collin 的建议使用完成块。模式是,如下所示︰

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

这可以从任何地方调用,并将永远不会阻塞。

官方微信
官方QQ群
31647020