Tag: multithreading

iOSmultithreading – NSURLSession和UI更新

我在iOS有一个关于multithreading的一般问题: 在我非常简单的testing应用程序中,我使用NSURLSession从服务器下载一些小图像并将它们呈现在表格视图中。 在NSURLSession的callback中,在检索图像之后,我调用tableview.reloadData(),如下所示: var session = NSURLSession.sharedSession().dataTaskWithURL(NSURL(url)) {(data, response, error) -> Void in /* Process images here */ self.tableView.reloadData() } session.resume() 图像几乎是即时下载,但需要10-20秒才能更新表格视图! 要清楚的是,更新代表甚至没有被调用 10-20秒。 但是,如果我将reloadData()放在主线程上,它会很快更新。 像这样: var session = NSURLSession.sharedSession().dataTaskWithURL(NSURL(url)) {(data, response, error) -> Void in /* Process images here */ dispatch_async(dispatch_get_main_queue()) { self.tableView.reloadData() } } session.resume() 所以,我的问题解决了,我可以再睡一会了。 但有人可以向我解释为什么是这样吗? 我知道UI更新应该在主线程中执行 – 那么为什么第一个案例实际上仍然可以工作,但是还是需要FOREVER来完成呢? 应用程序中没有任何其他的事情,所以我甚至不能开始思考什么可能会阻止整个20秒重新加载。 它是否等待NSURLSession首先完全closures,或者沿着这些线? 寻找大素数? […]

在目标C中序列化asynchronous任务

我希望能够序列化“真正的”asynchronous方法,例如: 提出networking请求 显示一个UIAlertView 这通常是一个棘手的业务,大多数串行队列样本在NSBlockOperation的块中显示“睡眠”。 这不起作用,因为操作只在callback发生时完成。 我已经通过inheritanceNSOperation来实现这个,下面是实现中最有趣的部分: + (MYOperation *)operationWithBlock:(CompleteBlock)block { MYOperation *operation = [[MYOperation alloc] init]; operation.block = block; return operation; } – (void)start { [self willChangeValueForKey:@"isExecuting"]; self.executing = YES; [self didChangeValueForKey:@"isExecuting"]; if (self.block) { self.block(self); } } – (void)finish { [self willChangeValueForKey:@"isExecuting"]; [self willChangeValueForKey:@"isFinished"]; self.executing = NO; self.finished = YES; [self didChangeValueForKey:@"isExecuting"]; [self didChangeValueForKey:@"isFinished"]; […]

检测performSelectorInBackground的结束:withObject:

我有我的iOS应用程序中的asynchronous服务器请求: [self performSelectorInBackground:@selector(doSomething) withObject:nil]; 我怎样才能检测到这个操作的结束?

有一个GCD队列的队列字典

我非常喜欢threadDictionary中的threadDictionary属性:非常方便的存储每个线程的所有权。 有一个GCD队列的等价字典?

UIProgressView不更新?

我已经开始在iOS5中使用UIProgressView,但没有真正运气。 我无法更新视图。 我有一套连续的行动,每次我更新进度后。 问题是,进度视图不是一点一点更新,而是完成之后。 它是这样的: float cnt = 0.2; for (Photo *photo in [Photo photos]) { [photos addObject:[photo createJSON]]; [progressBar setProgress:cnt animated:YES]; cnt += 0.2; } 浏览堆栈溢出,我发现这些post – setProgress不再更新UIProgressView自iOS 5以来 ,暗示为了这个工作,我需要运行一个单独的线程。 我想澄清这一点,我真的需要单独的线程为UIProgressView正常工作?

在当前队列上同步分派

我知道你可能会发现这是一个奇怪的问题,但我只是学习GCD,我想完全理解它的所有方面。 所以这里是: 是否有任何理由在CURRENT QUEUE上派发任务SYNC? 例如: dispatch_queue_t concurrentQueue = dispatch_get_global_queue(…); dispatch_async(concurrentQueue, ^{ //this is work task 0 //first do something here, then suddenly: dispatch_sync(concurrentQueue, ^{ //work task 1 }); //continue work task 0 }); 我明白了一件事情:如果不是concurrentQueue而是使用一个串行队列,那么我会在该串行队列上发生死锁,因为work task 1在work task 0完成之前不能启动(因为保证执行顺序的串行队列) ,同时work task 0不能继续执行,因为它等待SYNC dispath函数返回(如果我错了,请纠正我,这将使我总是noob)。 所以回到原来的想法,上面的代码和相同的代码之间有什么区别,而不是调用dispatch_sync函数,我直接写work task 1代码?

在后台线程上执行的领域写入仍然阻止主UI

在我的应用程序中,我需要对Realm执行大量的写入操作,任何地方都有100到10,000个对象。 显然这是一个大的写,所以我试图在后台执行这个写,使用户可以执行其他操作,甚至没有注意到写。 不幸的是,即使我认为我的写入是在后台线程上执行的,主UI仍然被阻塞。 这里是我打电话来执行写入领域的方法的jist。 这个方法是从我正在循环的数组中的单个对象重复调用。 它看起来像我做任何公然错误的? 任何帮助将不胜感激。 func writeCustomerToRealm(inputCustomer:Customer) { let qualityOfServiceClass = QOS_CLASS_BACKGROUND let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0) dispatch_async(backgroundQueue, { let realm = try! Realm() realm.beginWrite() realm.add(self.swapCustomerForRealmCustomer(inputCustomer)) try! realm.commitWrite() }) }

UIDocument&NSFileWrapper体系结构和性能

最近,我们将代码转换为使用UIDocument,而不是直接在文件系统上操作文件,因此我们遇到了一些性能问题。 我们想知道,如果其他人有这些问题,我们是否错误地使用这个类,以及解决这些问题的常用方法是什么。 我们的应用 我们有一个“shoebox应用程序”,用于pipe理一系列文件,每个文件都包含多个可能相当重的图像文件,一个小的元数据文件和一个小的预览图像。 用户可能在设备上有多个文档(超过1000个文档)。 每个文档的文件分组在一个目录中,我们使用NSFileWrapper来读写它们。 当我们的应用程序启动时,它需要所有文档的元数据以显示文档索引和预览图像的子集。 用户滚动时加载更多的预览图像。 为了获取这些信息,我们打开所有的文档,阅读他们的元数据和预览图像,如果需要的话,closures它们,然后再次打开。 问题1:加载速度慢 打开所有文档并阅读其元数据需要很长时间。 我认为这个问题有几个原因: – 每个文档的打开动作相对较慢 – 打开的文档块和完成块在同一个队列上执行,这使得操作的延迟非常糟糕(我的文档是打开的,但是完成块必须等待X打开文档块才能运行) 我们考虑使用单独的索引文件来解决这个问题,但是这种方法的缺点是我们需要在两个地方pipe理元数据,而且我们需要保持与文件系统的同步,以防iCloud更改文件。 问题#2:线程 每个打开的文档创build自己的“文件访问线程”。 当我们同时打开许多文档时,开销会压碎应用程序。 我们通过使用信号量来同步打开的操作来解决这个问题。 这种方法有一个缺点,它会减慢加载的速度。 问题 我们使用UIDocument的方式有一些基本问题吗? 如果不: 有没有人遇到类似的加载时间问题? 解决这个问题的常用方法是什么? 其他应用程序保持索引文件? 有没有办法让UI文件使用线程池? 如果不是,那么如何控制资源使用? 谢谢!

multithreadingGLKView绘图

我的主视图控制器包含许多子视图。 一个这样的子视图是GLKView链接到一个GLKViewController 。 GLKViewController似乎是负责更新GLKView的显示,而GLKView正在主线程上调用该更新函数。 我在这个主视图控制器中的其他视图之一是UITableView 。 当用户与表格视图交互时, GLKView停止更新。 我承认,我是OGL ES编程的新手,所以我不知道如何处理这个问题。 我需要得到GLKViewController的 – (void)glkView:(GLKView *)view drawInRect:(CGRect)rect; 方法在主线程的一个单独的线程上调用,所以我可以保持GLKViewanimation,而用户正在与其他元素交互。

NSObjectInaccessibleException',原因:'CoreData不能履行一个错误

我的iOS应用程序通过多个线程使用核心数据。 我得到一些崩溃报告,并带有以下消息:“'NSObjectInaccessibleException',原因:'CoreData无法履行'0x1e07a9b0'的错误 我明白是什么导致这个问题 – 对象被删除,但另一个线程试图访问它。 我正在努力解决这个问题,但我想在后台线程添加一个检查,看看对象是否会以这种方式错误。 我目前的代码与myObject.myValue 。 是否可以做一些检查,如: if (!myObject.myValue) { return; } …在做任何可能导致这样的崩溃的事情之前,它会摆脱这种方法? 或者只是简单地调用myObject.myValue ,甚至看它是否为空,导致这样的exception被抛出?