Tag: multithreading

UIGraphicsBeginImageContextWithOptions和multithreading

我对UIGraphicsBeginImageContextWithOptions和线程有点困惑,因为根据UIKit函数参考 UIGraphicsBeginImageContextWithOptions只能在主线程上调用。 当被调用的时候,它会创build一个基于位图的上下文,这个上下文可以用CoreGraphics的函数或者像drawInRect: for UIImage , -drawInRect:withFont: for NSString等方法来处理。 对于CoreGraphics的绘图,一切都很清楚 – 你将一个CGContextRefparameter passing给每个函数,但UIKit绘图方法使用栈中的当前上下文。 在iOS 4.0新增function的发行说明中写道 在UIKit中绘制graphics上下文现在是线程安全的。 特别: – 用于访问和操作graphics的例程 上下文现在可以正确处理驻留在不同线程上的上下文。 – string和图像绘制现在是线程安全的。 – 在多个线程中使用颜色和字体对象现在是安全的。 到现在为止还挺好。 有趣的部分是我有一个项目,在那里我通过创buildUIGraphicsBeginImageContextWithOptions上下文创build了多个图像,并创build了多个图像,但是当这些操作碰巧比较费时,我只是在后台线程中移动绘图,一些animation显示在屏幕上,一切正常 – 没有崩溃,没有泄漏。 图像绘制,因为它们是预期的,它似乎UIGraphicsBeginImageContextWithOptions为后台线程创build一个上下文,一切似乎都很好。 所以我的问题是: – 为什么有必要只调用UIGraphicsBeginImageContextWithOptions在主线程,因为它似乎在后台工作正常? – 如何使用UIImage的-drawInRect:方法在后台线程中,我没有当前的上下文,我似乎无法创build一个,因为我不能在那里调用UIGraphicsBeginImageContextWithOptions ? – 什么是正确的方法来使用UIKit的方法背景image processing(我知道我也可以使用CGBitmapContextCreate ,但它既不推动创build的上下文到上下文堆栈,我似乎也能够做到这一点,以便使用-drawInRect: UIImage方法)?

是OpenGL线程安全的多个线程与不同的上下文?

我知道在线程之间共享一个上下文是个坏消息。 我知道,当主线程上的GL没有发生任何事情时,我可以安全地在辅助线程上创build和使用带有屏幕外帧缓冲区的上下文。 对于是否可以在两个不同的线程上安全地创build两个上下文(比如,一个主线程在屏幕上绘图,另一个线程在屏幕外绘制工作),我还没有find一个明确的答案,并让他们同时进行GL函数调用。 换句话说,只要上下文不同,两个线程可以“共享”C API,从而GPU? 或者,这固有的东西是不可共享的? 或者是这个实现特定的? 在iOS上特别要求OpenGL ES,但这可能是一个普遍的GL问题。

如何包装一个asynchronous方法,它将一个块转换为同步的目标c

我想包装一个看起来像这样的asynchronousAPI: [someObject completeTaskWithCompletionHandler:^(NSString *result) { }]; 转换成我可以这样调用的同步方法 NSString *result = [someObject completeTaskSynchronously]; 我该怎么做呢? 我做了一些文档阅读和谷歌search,并尝试使用“dispatch_semaphore”来尝试实现它像这样: -(NSString *) completeTaskSynchronously { __block NSString *returnResult; self.semaphore = dispatch_semaphore_create(0); [self completeTaskWithCompletionHandler:^(NSString *result) { resultResult = result; dispatch_semaphore_signal(self.semaphore); }]; dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER); return resultResult; } 但这似乎没有工作,它基本上只是停在dispatch_semaphore_wait。 执行永远不会到达_signal的内部块。 任何人都有代码示例如何做到这一点? 我怀疑该块必须在主线程以外的其他线程? 另外,假设我没有访问async方法背后的源代码。 谢谢!

NSOperation阻止UI绘画?

我在使用NSOperation和绘图之后有一些build议: 我有一个主线程创build我的NSOperation子类,然后将其添加到NSOperationQueue 。 我的NSOperation做了一些繁重的处理,它打算在main()方法中循环几分钟,不断地处理一些工作,但是现在我只是有一个while()循环,里面有一个sleep(1),它被设置为5次左右(testing)。 产生这个NSOperation的主(原始)线程负责绘制到视图和更新UI。 我打算让NSOperation线程使用一个通知来告诉主线程它已经完成了一些处理,现在这个通知每一次发送一次,通过它的while()循环发送一次(也就是每秒一次,因为它只是在睡觉(1))。 主线程(视图),注册以接收这些通知。 通知立即通过主线程,看起来asynchronous,看起来很好。 看来,两个线程按预期运行…这是 – 同时。 (我使用NSLog()只是大致检查每个线程发送和接收通知)。 当视图接收到一个通知,并且它的处理方法被调用时,我只需递增一个整型variables,然后试着将其绘制到视图中(作为一个当然的string)。 在testing中,drawRect中的代码:将这个整数(作为string)绘制到屏幕上。 然而,这里是我的问题(对不起,需要一点时间来到这里):当主线程(视图)从NSOperation接收到通知时,它更新此testing整数并调用[self setNeedsDisplay]。 但是,直到NSOperation完成之后,视图才会重绘! 我期望NSOperation,作为一个单独的线程,将无法阻止主线程的事件循环,但似乎这是发生了什么事情。 当NSOperation完成并且它的main()返回时,视图最终重新绘制自己。 也许我没有正确使用NSOperation 。 我在“非并发”模式下使用它,但尽pipe名字我的理解是,这仍然产生一个新的线程,并允许asynchronous处理。 任何帮助或build议非常感谢,如果你想看到一些代码只是让我知道。

苹果文档的GCD生产者 – 消费者解决scheme错误?

在Apple的“并发编程指南”的“从线程迁移”一节中,有 改变生产者 – 消费者实现 ,它宣称使用GCD可以简化典型的多步骤线程互斥+条件variables实现。 通过调度队列,可以将生产者和消费者实现简化为一个调用: dispatch_async(queue, ^{ // Process a work item. }); 当您的生产者完成工作时,所要做的就是将该工作添加到队列中,让队列处理该项目。 生产者 – 消费者问题也被称为有界缓冲区问题,但是上面没有提到缓冲区,其边界或消费者,更不用说阻止生产者和消费者,以避免过度/不足的运行。 这怎么可能是一个有效的解决scheme?

核心数据pipe理对象上下文devisebuild议

我们正在研究一个企业级的应用程序,它将存储数以万计的核心数据对象,我们在几个方面都有问题。 我们的应用程序有几个独立的系统,在需要时对数据进行操作。 这些系统包括项目的发现,项目的加载,同步和UI显示。 如果我们正确地devise我们的软件,由于不同的系统修改相同的对象,应该有很less的甚至没有合并冲突。 每个系统都有自己的操作队列,全部在后台执行。 我们希望在后台保留所有对象的创build和修改,以最大限度地减lessUI性能问题,特别是在初始阶段,可能会从服务器上的数据创build数千个对象。 在这里我们遇到了几个与我们的各种devise尝试的问题。 在这些上升过程中巨大的内存消耗,以及所有上下文和子上下文的错误编排,导致死锁和崩溃。 我们尝试了以下devise: 一个拥有一个子NSMainQueueConcurrencyType上下文的根NSPrivateQueueConcurrencyType托pipe对象上下文。 UI获取的结果控制器使用此子上下文从中获取结果。 从NSMainQueueConcurrencyType子上下文中,我们创build了一个NSPrivateQueueConcurrencyType子上下文,我们称之为“savingContext”,每个后台操作创build了“savingContext”的子上下文,做了修改,最后做了我们所谓的“深度保存”保存到顶部。 我们最初select这种devise,不必处理来自许多不同的子上下文的NSManagedObjectContextDidSaveNotification通知。 我们将每个调用都包装到NSPrivateQueueConcurrencyType上下文中,并使用performBlockAndWait:来访问对象。 在function上,这个devise进行。 所有更改和插入已保存到持久性存储,并更新了UI的更改。 这个,介绍了两个问题。 其中一个是laggy UI,因为合并后的更改通过NSMainQueueConcurrencyType子上下文,更重要的是,在启动期间非常高的内存使用率。 由于无法在上下文上recursion调用reset (因为主UI子上下文也存在)和/或缺less何时调用refreshObject:mergeChanges: 所以我们走了一条不同的路 有两个顶级上下文链接到持久性存储协调器,一个用于保存子上下文的NSMainQueueConcurrencyType和一个用于UI显示的NSMainQueueConcurrencyType 。 NSMainQueueConcurrencyType侦听来自主NSPrivateQueueConcurrencyType上下文的NSManagedObjectContextDidSaveNotification通知,并将它们合并到主线程中。 每个后台操作都创build主NSPrivateQueueConcurrencyType上下文的子上下文,也使用私有队列并发types,做它所做的事情,recursion地执行“深度保存”,在当前上下文执行保存,深度保存到其上下文的recursion调用父母,调用当前上下文重置并再次保存。 这样我们可以避免内存问题,因为创build的对象在保存后快速释放。 但是,通过这种devise,我们遇到了很多问题,例如NSInternalInconsistencyException , NSInternalInconsistencyExceptionexception和获取的结果控制器不更新UI,尽pipe保存NSMainQueueConcurrencyType上下文的通知。 这也会导致UI中的初始加载时间减慢很多。 在之前的devise中,抓取的结果控制器返回结果的速度非常快,而这会阻塞UI几秒钟,直到视图加载(我们在viewDidLoad初始化抓取的结果控制器)。 我们已经尝试了许多中间devise,但都围绕相同的问题,无论是非常高的内存使用率,获取的结果控制器不更新UI或死锁和NSInternalInconsistencyExceptionexception。 我真的感到沮丧。 我不得不觉得,我们的devise显然是复杂的,应该是相当简单的事情,只是我们不了解一些基本的东西正在杀死我们。 那么你们会build议什么? 你会根据我们的情况推荐什么样的安排? 我们应该如何在不同的线程中pipe理不同的上下文? 释放插入的对象和重置上下文的最佳实践? 避免死锁? 所有的帮助,将在此时赞赏。 我也看到了MagicalRecords类别的build议。 是否推荐? 我们已经投入使用核心数据types,使用MR迁移有多困难?

需要关于调度队列,线程和NSRunLoop的一些说明

以下是我所知道和了解的内容: 全局队列是一个可以将任务分派给多个线程的并发队列。 执行任务的顺序不能保证。 例如: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { for (int i; i<10; i++) { doTask() } }) 如果我想调度到串行队列,我可以使用 dispatch_async(dispatch_queue_create("my.serial.queue", nil) { … } 每次只有一个任务被调度到一个线程并被执行。 订单是先进先出。 =====我感到困惑和不完全理解======= 主线程有一个NSRunLoop,在主线程中循环任务。 我想知道调度队列和运行循环之间的关系是什么? 我可以理解,如果调度一个任务到主线程,主线程的NSRunLoop得到调度任务并执行它? 把任务分派给多个线程的全局队列呢? iOS / OSX系统不仅自动创build线程,还为每个线程创buildNSRunLoop? 然后每个线程的运行循环从全局队列中获取调度的任务并执行它? 谁知道线程? dispatch_async()和dispatch_sync()函数知道哪个线程调度任务,或者队列知道哪个线程调度任务? 有没有办法从程序调度队列中获取线程的NSRunLoop对象(调度任务)? (这个问题与问题3有关)

objc_sync_enter / objc_sync_exit不适用于DISPATCH_QUEUE_PRIORITY_LOW

我需要一个读/写locking我的应用程序。 我读过https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock 并写了我自己的类,因为没有快速读/写锁 class ReadWriteLock { var logging = true var b = 0 let r = "vdsbsdbs" // string1 for locking let g = "VSDBVSDBSDBNSDN" // string2 for locking func waitAndStartWriting() { log("wait Writing") objc_sync_enter(g) log("enter writing") } func finishWriting() { objc_sync_exit(g) log("exit writing") } // ждет пока все чтение завершится чтобы начать чтение […]

iOS GCD:任何全局队列和具有后台优先级(DISPATCH_QUEUE_PRIORITY_BACKGROUND)之间的区别?

我正在阅读并发编程指南和东西混淆了我。 我看到很多代码调用以下任何后台任务: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 现在我所说的“背景”是stream行的意思: 除了主(UI)线程之外的任何地方执行的东西 因此,在文档之后,上面的语句返回具有不同优先级的任何非主线程队列。 我的问题是 – 为什么然后DISPATCH_QUEUE_PRIORITY_BACKGROUND存在? 最近我还看到许多使用DISPATCH_QUEUE_PRIORITY_BACKGROUNDasynchronous任务来执行后台任务。 DISPATCH_QUEUE_PRIORITY_DEFAULT , DISPATCH_QUEUE_PRIORITY_LOW或DISPATCH_QUEUE_PRIORITY_HIGH返回的队列是否与主线程相距甚远,如果使用dispatch_get_global_queue返回? 他们不是背景排队吗? 用DISPATCH_QUEUE_PRIORITY_BACKGROUND返回的队列有什么具体的用途? 我已经提到了这个,但是除了上面提到的stream行的含义之外,它没有多less澄清。 我相信我很迷茫的话 – 背景和背景排队。 如果有人可以解释(更好,graphics) – 将是一个很大的帮助。

GCD,NSThread或NSOperationQueue中哪一个最好?

我们有三个选项GCD, NSThread和NSOperationQueue ,iOS中multithreading的最佳方式是什么? 我很困惑哪一个是最好的? 如果没有,那么应该在什么情况下使用,以及它们如何不同,以及如果有人使用NSOperationQueue一些很好的例子,请分享,以便我可以学习。