Tag: grand central dispatch

两个同时使用NSOperationQueue的后台任务

我有两个任务需要在不同的线程优先级中同时执行: 不断地收集和处理陀螺仪运动数据(高优先级) gyroQueue = [[NSOperationQueue alloc] init]; [self.motionManager startDeviceMotionUpdatesToQueue:gyroQueue withHandler:^(CMDeviceMotion *motion, NSError *error){ [self processMotion:motion withError:error]; }]; 有时在不干扰运动更新的情况下处理图像(转换,裁剪,分割等= 1-2秒)(非常低的优先级) imageProcessingQueue = [[NSOperationQueue alloc] init]; [imageProcessingQueue addOperationWithBlock:^{ [self processImage:[UIImage imageWithData:imageData]]; }]; 编辑:这是我原来的地方(而不是块操作),它仍然阻止运动更新: NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(processImage:) object:[UIImage imageWithData:imageData]]; [operation setThreadPriority:0.0]; [operation setQueuePriority:0.0]; [imageProcessingQueue addOperation:operation]; 看起来这两个任务都在同一个后台线程上执行(由于NSOperationQueue性质?),并且处理图像会阻塞陀螺队列更新直到完成,这就是我想要避免的。 我如何使用NSOperationQueue产生两个单独的线程,并相应地分配非常高和非常低的优先级? 编辑:这个问题仍然是开放的,我正在使用特劳沃哈蒙的图像resizefunction的图像resize。 有人可以确认它是否线程安全?

如何在大型中央调度操作中运行asynchronous操作?

我有一个需要处理的作业队列,队列由定时器周期性地踢,而且当新的作业被添加到队列时,也通过调用线程。 当队列被踢时,我想在另一个线程上启动对队列的处理,因为我不想阻塞调用线程(在很多情况下这将是UI线程)。 所以为此,我对高优先级的并发队列运行一个macros中央调度操作,这会创build一个我的http类的实例,并通过它提交作业(作业基本上是一个http请求)。 http类在内部使用NSURLConnection执行asynchronous请求。 我的问题是GCD操作完成(因为它已经提交了所有的asynchronousHTTP请求),所以我猜它正在运行的线程要么清理,重用或退出。 这是消灭我的http类正在做这些asynchronousWeb请求的过程中。 我的问题是,如何让我的http类挂起,完成处理请求而不使GCD操作等待呢? 干杯

GCD dispatch_after调用引起SIGBUS信号

我正在使用GCD的dispatch_after方法,当我的应用程序被加载执行一些行为。 预期的行为是从applicationDidFinishLaunchingWithOptions结束等待3秒,以执行在后台队列中运行的select器。 我的testing设备上没有遇到任何崩溃,但是我有用户崩溃报告了未捕获的SIGBUS信号,原因是BUS_ADRALNexception。 从我对此代码的理解中,BUS_ADRALN错误表示地址alignment错误。 这是我如何创build我的计时器: double delayInSeconds = 3.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void){ [self methodToPerformInBackground]; }); 什么可能导致这次崩溃? 因为multithreading错误可能是一种奇怪的东西,所以我会抛出一些我一直在脑海中徘徊的想法。 我打电话给[self performSelectorOnMainThread:withObject:waitUntilDone] 。 在这样的select器中做这个问题有什么问题吗? 由于我打电话dispatch_get_global_queue而不是dispatch_create_queue ,我不需要保留这个方法返回的队列。 这个推理是否正确? 在这个代码中, self是应用程序委托。 在应用程序进入后台或终止之后,是否可能导致崩溃? 应用程序在closures时是否自动清理所有调度的块? 被调用方法内部的东西导致崩溃,但GCD不提供堆栈跟踪。 编辑:我宁愿不包括块中调用的代码,因为我不相信这是主要的问题。 这是堆栈跟踪。 线程0上的崩溃使得仿佛问题出现在GCD中,而不是块中调用的代码。 编辑#2:通过更多的崩溃报告,我有奇怪的消息分享。 此崩溃只出现在运行iOS 4.2.X及更低版本的用户上。 由于iOS 4.0及更高版本支持GCD,因此我的猜测是在4.3中修正了一个bug。 Thread 0 Crashed: 0 libSystem.B.dylib 0x35e5fb10 _dispatch_retain + 0 1 […]

大中央调度快速堆积增长

背景:我有一个使用GCD的iOS游戏应用程序。 对于应用程序,我有三个队列:主队列,游戏逻辑队列(自定义串行),物理队列(自定义串行)。 物理队列是用来做物理模拟和游戏队列是用来做游戏的逻辑。 因此,对于每次更新(每1/60秒),每个队列执行相应的工作,然后通过在其他队列上调度块来与其他队列共享。 问题: 使用GCD:当我玩游戏级别,即队列正在做一些工作时,我看到我的堆/分配非常迅速的增长,导致应用程序崩溃,由于内存问题。 如果我退出关卡并进入非游戏视图,即队列没有任何工作,内存缓慢下降(大约2分钟),并变得稳定。 在附图中,图片中的高峰就在我离开游戏关卡之前出现在外面。 之后,随着对象被释放,内存会有一个稳定的下降。 没有GCD:如果我禁用其他两个队列并在主队列上运行所有内容,即从代码中消除所有并发,我看不到任何显着的堆增长,游戏运行良好。 已经在互联网上研究/尝试过/研究过:我对块捕获和块被复制到堆的概念有一个简单的理解,但是我不太确定。 就我的理解而言,我在代码中找不到任何这样的对象,因为当我退出游戏级别并进入非游戏视图时,所有预期将被释放的对象都将被释放。 问题: 与GCD的应用程序创build了很多块。 创build大量的块是一个好习惯吗? 在正在运行的乐器上,我发现快速分配但没有发布的对象是Malloc 48类。这些对象的负责任的库是libsystem_blocks.dylib,负责的调用者是_Block_copy_internal。 一旦我退出游戏级别,即队列停止执行任何工作,这些对象就会慢慢地被释放。 但是,释放非常缓慢,大约需要2分钟才能完全清理。 有没有什么办法可以加快清理呢? 我的怀疑是物体不断堆积,然后导致内存崩溃。 任何想法可能会发生什么? 提前致谢。 根据以下评论的build议,我写了下面的testing代码。 我基本上从一个CADisplayLink调度回来,然后在callback我排定5000个块到自定义队列。 // In a simple bare-bones view controller template I wrote the following code – (void)viewDidLoad { [super viewDidLoad]; self.objDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(loop:)]; [self.objDisplayLink setFrameInterval:1/60]; [self.objDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } […]

当应用程序放置在后台时,GCD调度操作不能运行

我启动一个方法,实质上是一个使用dispatch_queue_create然后dispatch_async (然后代码循环在调度块内)的无限循环。 循环运行完美。 但是,当应用程序停止时,它会暂停。 然后在应用程序占据前景时重新启动。 我怎样才能防止这种情况发生? 我一直在这里看,但似乎优先事项不是我可以select的东西之一。

使用GCD连续显示多个视图

我有4个选项卡,都有UIWebView 。 我希望第一个选项卡应该加载并立即显示,而无需等待其他人加载。 为此我在UITabBarController类中做了这个: for(UIViewController * viewController in self.viewControllers){ if(![[NSUserDefaults standardUserDefaults]boolForKey:@"isSessionExpired"]) { if((int)[self.viewControllers indexOfObject:viewController] != 4) { viewController.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:viewController]; [viewController view]; } } } 但主线程等待所有制表符加载。 我试着用GCD使用dispatch_async dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1 dispatch_async(dispatch_get_main_queue(), ^{ UIViewController *firstContrl = [self.viewControllers objectAtIndex:0]; firstContrl.tabBarItem.tag = (int)[[self viewControllers] indexOfObject:firstContrl]; [firstContrl view]; dispatch_async(dispatch_get_main_queue(), ^{ // 2 UIViewController *secContrl = […]

如果dispatch_sync不使用不同的线程,它可以更快吗?

我正在运行这个代码 dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ NSLog(@"Main Thread? %d", [NSThread isMainThread]); // non-trivial non-UI code here }); NSLog表明我实际上是在主线程上,但是…我的印象是,如果我使用dispatch_sync (而不是什么),非平凡的非UI代码运行速度会快得多。 如果它在主线程上运行,有什么办法可以更快?

ALAssetLibrary通知和enumerateAssetsUsingBlock

我正在构build一个iOS应用程序,允许用户拍摄照片并将其保存到自定义相册中,该应用程序使用相册中的照片在应用程序中填充UICollectionView。 我在网上find了很多关于如何做到这一点的例子,但是我不能在最近的一张专辑中没有显示出来的问题。 我结束了使用通知和串行调度队列的工作,但是我认为可以改进。 以下是我如何保存图片,然后重新填充UICollectionView: 我build立了一个方法来调用,当我需要枚举相册(viewDidLoad,一旦我收到了ALAssetsLibraryChangedNotification)。 -(void)setupCollectionView { _assets = [@[] mutableCopy]; __block NSMutableArray *tmpAssets = [@[] mutableCopy]; // This grabs a static instance of the ALAssetsLibrary ALAssetsLibrary *assetsLibrary = [ProfileViewController defaultAssetsLibrary]; // Enumerate through all of the ALAssets (photos) in the user's Asset Groups (Folders) [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) { if ([[group valueForProperty:ALAssetsGroupPropertyName] […]

CoreData与GCD队列中的AFNetworking请求不兼容?

我正在使用GCD启动一个长期运行的后台进程('run_loop'),它创build一个NSManagedObjectContext('MOC'),监视CoreData对象,有时(准备好的时候)将它们的序列化上传到一个Web服务器,然后删除它们。 我正在使用AFNetworking进行HTTP调用。 问题在于请求完成处理程序块,因为这些块在不同的线程中运行,而不是由CoreData支持的MOC所有者。 我已经尝试从GCD run_loop块的开始存储NSThread,并使用performSelector:onThread:run_thread,但这似乎并没有真正调用select器。 我曾尝试使用dispatch_sync(run_queue),但这并不保证线程是一样的,只有GCD队列。 主线程中保存的另一个MOC稍后挂起。 最终,唯一有效的工作是在完成callback处理程序中设置布尔值,并引入额外的逻辑来检测布尔开关,并从主run_loop执行MOC工作。 任何人都可以build议一个更优雅的修复? 或者CoreData与从GCD队列启动的AFNetworking请求不兼容,我应该从头看一下低级的线程控制?

如何通过NSOperation来实现并发任务?

我是NSoperation 。 NSoperation是一个单选对象。 我们怎样才能通过NSoperation操作同时实现多个操作? 是否有可能没有NSoperationQueue ? 即使我们使用NSoperationQueue,它也会执行操作FIFO格式。它将如何同时执行?