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

Ios 如何从Grand Central Dispatch中获取阵列?,ios,multithreading,concurrency,grand-central-dispatch,Ios,Multithreading,Concurrency,Grand Central Dispatch,我是个新手。我正在使用Grand Central Dispatch在另一个线程上填充一个数组(student_temp)。那部分很好用。问题是我无法将数组传递给类属性(student_数组),在该属性中它在整个类中使用。我无法将数组恢复到主线程上 它工作正常,直到我回到主线程,我不能将student_temp传递到GCD内部或外部的student_数组(属性) 我做错了什么,或者使用GCD填充数组属性有更好的方法吗 谢谢你的帮助。如果可能的话,请试着用非技术性的语言解释我对这方面还不熟悉 - (

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

它工作正常,直到我回到主线程,我不能将student_temp传递到GCD内部或外部的student_数组(属性)

我做错了什么,或者使用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;

您应该能够直接从块向
student\u数组添加对象。与堆栈变量不同,属性和IVAR在块中使用时不会被复制。相反,
self
保留在块中,并通过它引用属性

当然,您需要注意并发性问题,例如,如果您也需要从主线程访问数据。为此,您可能仍然希望在异步GCD块的末尾有以下内容:

// done populating the data
dispatch_async(dispatch_get_main_queue(), ^{
   // update the UI
}
一些反应:

  • 在代码的最后一行,您将
    student\u Array
    设置为
    student\u temp
    。显然,这一行毫无意义,因为您正在异步填充
    student\u temp
    。如果您试图在两个队列中同时访问save变量,那么您将面临同步问题。不要费心在
    viewDidLoad
    的末尾将
    student\u数组分配给
    student\u temp
    ,只需在嵌套的
    dispatch\u async
    调用中执行即可

  • 在块内,您正在填充和设置
    student\u temp
    。将该变量限定在该块内可能更有意义,避免了从该块外访问它的诱惑,并简化了代码,因为不再需要
    \u块
    限定符

  • 此块是异步运行的,因此当您更新主队列中的
    student\u Array
    时,您可能希望同时更新UI(例如,重新加载tableview或其他内容)。也许你已经这么做了,只是为了简洁起见把它去掉了,但我只是想确定一下

  • 因此:


    什么是学生阵列工作!非常感谢!!我花了好几天时间在这上面。所以我猜重载数据只是告诉程序继续在主线程上工作?我想我需要将它发送到旧的主线程,但我想主线程只是从这里重新启动。不管怎样,它是有效的。再次谢谢你斯蒂芬:这不是说它应该“继续在主线程上工作”。主线程从未停止过。只是当加载视图时,调用
    viewDidLoad
    方法,然后调用
    UITableViewDataSource
    方法。但是您编写的这个“获取数据”代码块是异步运行的,这意味着在
    UITableViewDataSource
    方法完成后,它可能会很好地完成,并且表视图无法知道它需要重新加载数据,除非您告诉它这样做。
    - (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];
            });
        });
    }