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