ios - 如何从异步属性的 getter 返回?

标签 ios objective-c grand-central-dispatch getter-setter

我已经覆盖了一个请求在线服务以获得结果的 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_asyncdispatch_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/

相关文章:

ios - 插件工具包 : -[PKService run] iOS Keyboard extension error

objective-c - 为什么 tochesBegan 在 UITableView 中不起作用?

objective-c - 如何通过按钮将 segue 从一个 View Controller 推送到另一个 View Controller ?

ios - 在 Swift 中使用 dispatchGroup 处理一系列异步函数时出错

ios - 我如何将带有参数的请求放入 NSArray 并稍后在循环中调用?

ios - keychain iOS touchId 提示两次

iphone - Phonegap-无法从JavaScript调用本地iOS功能

ios - UIButton自定义字体问题

ios - indexPath.row 返回最后一个可见单元格,并且没有调用 didSelectRowAtIndexPath

iphone - 为什么在使用全局调度队列时不调用 NSURLConnection 委托(delegate)方法?