访问通过多个调度队列块传递的对象中的参数是否安全?

时间:2012-03-08 00:40:04

标签: ios grand-central-dispatch

假设我想在主UI中保持良好和快速,所以我将慢速部分分解为队列(使用全局并发队列)。假设在这种情况下selectedUser始终保持静态。

在一个View Controller中我有这样的东西:

- (IBAction)buttonPressed:(id)sender {

    User *selectedUser = [self getSelectedUser];

    dispatch_queue_t queue;
    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        @autoreleasepool {

            [userManager doSomething:selectedUser withForceOption:YES];

        }

    });

}

在另一个类中,我有一个单例定义(userManager),使用如下方法:

- (void)doSomething:(User*)user withForceOption:(BOOL)force {

    SAppDelegate *delegate = (SAppDelegate *)[UIApplication sharedApplication].delegate;
    extlib_main_queue = delegate.extlib_main_queue;

    dispatch_async(extlib_main_queue, ^{
        @autoreleasepool {
            extlib_status_t status;
            user.opIsStarting = YES;

            extlib_call_id callId = -1;

            // this is the part that worries me:
            extlib_str_t uri = extlib_str((char *) [[NSString stringWithFormat:@"http:%@@%s", user.account,DOMAIN] UTF8String]);
            status = extlib_call_make_call(0, &uri, 0, NULL, NULL, &callId);
        }

    });
}

我的问题是:执行此操作是否安全,或者我是否需要执行其他操作以确保两个块都可以访问传递的User实例的参数?

2 个答案:

答案 0 :(得分:2)

只要它们存活,User对象将被两个块保留。这里唯一的问题是User对象实际上可以安全地从不同的线程访问。

答案 1 :(得分:1)

您无需担心,因为块会保留它们引用的变量。

buttonPressed:中的块保留selectedUser,因为块引用它,doSomething:withForceOption:中的块保留user,因为其中的块也引用它。

阅读块编程主题的this section,了解有关其工作原理的更多详细信息。