如何从Grand Central Dispatch中获取阵列?

时间:2014-01-28 05:25:05

标签: ios multithreading concurrency grand-central-dispatch

我是新手。我正在使用Grand Central Dispatch在另一个线程上填充数组(student_temp)。那部分工作正常。问题是我不能将数组传递给类属性(student_Array),它在整个类中使用它。我无法在主线程上恢复数组。

它工作正常,直到我回到主线程,我无法将student_temp传递给GCD内部或外部的student_Array(属性)。

我做错了什么,或者使用GCD填充数组属性是否更好?

感谢您的帮助。如果可能的话,请尝试用非技术语言解释我是新手。

- (void)viewDidLoad
{
    [super viewDidLoad];

    R2LFetcher *studentFetch = [[R2LFetcher alloc] init];
    __block NSMutableArray *student_temp = [[NSMutableArray alloc] init];

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^{

        //long-running code goes here…
           student_temp  = [studentFetch fetchToStudentArray];

        dispatch_async(dispatch_get_main_queue(), ^{

            // code the updates the main thread (UI) here...
            student_Array = student_temp;

        });

    });
    student_Array = student_temp;

2 个答案:

答案 0 :(得分:0)

您应该可以直接从块中添加student_Array对象。与堆栈变量不同,在块内使用时,不会复制属性和ivars。相反,self会保留在块中,并通过它引用属性。

当然,您需要了解并发问题,例如:如果您还需要从主线程访问数据。为此,您可能仍希望在异步GCD块的末尾具有此功能:

// done populating the data
dispatch_async(dispatch_get_main_queue(), ^{
   // update the UI
}

答案 1 :(得分:0)

一些反应:

  1. 在代码的最后一行,您将student_Array设置为student_temp。很明显,这条线是没有意义的,因为你是异步填充student_temp。如果您尝试同时访问两个队列中的保存变量,那么您将面临同步问题。不要在student_Array的末尾将student_temp分配给viewDidLoad,而只是在嵌套的dispatch_async来电中进行。

  2. 在块中,您正在填充并设置student_temp。将该变量限定在该块中可能更有意义,避免诱惑从该块外部访问它以及简化代码,因为不再需要__block限定符。

  3. 此块以异步方式运行,因此当您更新主队列中的student_Array时,您可能希望同时更新UI(例如重新加载tableview或其他内容)。也许你已经这样做了,为了简洁起见就把它删除了,但我只是想确定一下。

  4. 因此:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
        dispatch_async(queue, ^{
    
            R2LFetcher *studentFetch = [[R2LFetcher alloc] init];
    
            // long-running code goes here, for example ...
    
            NSMutableArray *student_temp = [studentFetch fetchToStudentArray];
    
            dispatch_async(dispatch_get_main_queue(), ^{
    
                student_Array = student_temp;
    
                // code the updates the main thread (UI) here, for example...
    
                [self.tableView reloadData];
            });
        });
    }