Tag: 大中央调度

GCD和webView死锁

我发现了一个似乎在WebKit导致死锁的问题。 如果我从我的主线程运行这个代码,我正确地看到一个警报。 我可以点击警报上的“确定”button,它被解散,一切工作正常: [theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"]; 如果稍作修改,则警告消息仍会出现,但不能点击确定button – 您不能closures警报,并且如果进入应用程序,则会挂起在stringByEvaluatingJavaScriptFromString调用中: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ [theWebView stringByEvaluatingJavaScriptFromString:@"alert('hi');"]; }); }); 这两者唯一不同的是,第二个是在调度队列的上下文中的主线程中运行JS。 另一方面,如果我做了以下,那么挂起不会发生: – (void) showHi:(id) it { [(UIWebView*)it stringByEvaluatingJavaScriptFromString:@"alert('hi');"]; } …. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self performSelectorOnMainThread:@selector(showHi:) withObject:theWebView waitUntilDone:NO]; }); 有人能指出什么是错误的,导致挂起? 编辑: 相关问题: 使用dispatch_async或performSelectorOnMainThread在主线程上执行UI更改? 主队列上的performSelectorOnMainThread和dispatch_async有什么区别? Grand Central Dispatch(GCD)与performSelector – 需要更好的解释 非常类似的问题: 使用GCD调用时,UIWebView stringByEvaluatingJavaScriptFromString在iOS5.0 / 5.1上挂起

我们如何在iOS应用程序转到后台时调度Google Analytics事件?

我的iOS应用程序有链接到苹果的App Store中,我试图跟踪这些事件。 问题是,我们无法让我的应用程序在进入后台之前正确地分配GA事件。 我们正在使用iOS SDK v2beta4。 这里是我们正在使用的代码的概述。 你可以看到我们已经把很多我称之为“保险单”的代码,因为我们认为是正确的方式是行不通的。 但即使是保险政策代码,也不会在我的应用程序进入后台之前始终调度事件。 它只能工作大约50%的时间,其余的时间我不得不返回到应用程序来获取事件发送。 我们相信正确的方法是在“applicationDidEnterBackground”中派发事件,并通过“beginBackgroundTaskWithExpirationHandler”请求iOS额外的时间来完成此事。 我们已经尝试了这个代码,没有我的“保险单”代码。 至less我相信我们正确地评论了每一行保险代码。 请注意,我们设置全局variablesUIBackgroundTaskIdentifier bgTask; 在代码的AppDelegate.h头文件中 UIBackgroundTaskIdentifier bgTask; 这里是我们认为是正确的方法来做到这一点的代码: – (void)applicationDidEnterBackground:(UIApplication *)application { UIApplication *app = [UIApplication sharedApplication]; bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [[GAI sharedInstance] dispatch]; [app endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }); } 上面的代码是我们认为应该工作,但没有。 注意:App Store不是一个普通的应用程序,而是一个应用程序中的网站,如果这有所作为。 作为一项保单,我们已经做了一些其他事情约50%的时间派发事件: […]

澄清dispatch_queue,重入和死锁

我需要澄清dispatch_queue是如何与重入和死锁有关的。 阅读这篇博客文章, 在iOS / OS X上的线程安全基础知识 ,我遇到了这样一句话: 所有分派队列都是不可重入的,这意味着如果您尝试在当前队列上分派同步,则会发生死锁。 那么,重入和僵局之间的关系是什么呢? 为什么,如果一个dispatch_queue是不可重入的,当你使用dispatch_sync调用时会产生死锁? 在我的理解中,只有当你正在运行的线程与调度块所在的线程相同时,才可以使用dispatch_sync产生死锁。 一个简单的例子如下。 如果我在主线程中运行代码,由于dispatch_get_main_queue()也会占用主线程,所以我将以死锁结束。 dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"Deadlock!!!"); }); 任何澄清?

Grand Central调度和unit testing

我已经写了一个简单的testing用例,遵循苹果的文档 ,我没有看到我期待的结果。 代码如下: – (void)testExample2 { NSLog(@"1"); dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"3"); dispatch_semaphore_signal(semaphore); }); NSLog(@"2"); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"4"); dispatch_release(semaphore); } 我希望阅读:1,2,3,4,而是我的控制台只显示我1,3。 我已经能够在一个while循环中使用DISPATCH_TIME_NOW和NSLoop hack一起解决这个问题,但是上面的代码应该是一种工作…对吧? 干杯… UPDATE 我只是意识到,我应该使用一个单独的队列,而不是dispatch_main_queue()

syscall_thread_switch iOS 8.3比赛 – CocoaLumberjack的错误? 如何debugging呢?

我在我的应用程序中遇到竞争条件,每当我暂停debugging时,除了1个线程之外的所有或所有线程都卡在syscall_thread_switch上。 它在模拟器上复制的频率要高得多,而且在iPad Air上也是如此。 在CocoaLumberjack的queueLogMessage中至less有2个线程被阻塞: – 见截图。 我在8.1和8.2之前从来没有见过这个,但是我经常在8.3上看到它。 我不是声称这是一个8.3错误:) 这是一个复杂的程度,我从来没有debugging过,所以我不知道该怎么做。 我希望能够提供足够的信息,如果您需要更多信息,请告诉我们(如果信息不是很清楚的话,请具体说明如何获取信息)。 你能帮我debugging吗?! 数百万的感谢。

有一个GCD队列的队列字典

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

在后台线程上执行的领域写入仍然阻止主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() }) }

使用dispatch_sync作为互斥锁

这是我需要做的。 我希望dispatch_sync是使用GCD的最好方法 我有一些关键部分的代码放在Appdelegate的applicationDidBecomeActivecallback中。 我在dispatch_sync调用中封装了这个方法,所以无论调用了多less次的applicationDidBecomeActive,它只被调用一次 – (void)applicationDidBecomeActive:(UIApplication *)application{ dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"Thread created"); //crtical code [self runCriticalSection]; });} 这是使用dispatch_sync做正确的方法吗?

GCD与NSURLConnection

我正在使用GCDasynchronous发送HTTP请求。 以下是不起作用的代码: dispatch_async(connectionQueue, ^{ NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:[NSString stringWithFormat:someURL]]]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start];//Not working }); 上面的代码根本不起作用。 我在NSURLConnectionDelegate的方法中没有收到任何callback。 但是,当我尝试下面的代码,一切工作正常,我得到适当的callback NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:[NSString stringWithFormat:someURL]]]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; dispatch_async(connectionQueue, ^{ [connection start]; // working fine. But WHY ???? […]

UITableView insertRowsAtIndexPaths:WithRowAnimation不冻结用户界面

我试图了解什么是最好的做法,当我使用UITableView与大量的行插入时,表是可见的。 这是我的行为: 我有一个UITableView和一个线程,试图插入一个数据到这个表中。 我认为做一个[UITableView reloadData]是性能方面的一个糟糕的解决scheme,我知道UIKit操作是在主线程进行,因此,当数据源更新完成时,我试图发送一个NSNotification使UITableView更新操作(beginUpdate – insertRowAtIndex – endUpdate)在主线程上,但是这种技术冻结了用户界面。 我必须使用1000+以上的行数。 有人已经解决了这个问题? 是否可以使用GDCasynchronous和同步? 如果是的话,怎么样? 提前致谢。