Tag: 中央调度

为什么Objective-C / Swift中的asynchronousnetworkingtesting困难?

所以,当我遇到以下情况时,我正在学习更多关于如何testingasynchronous代码的知识: 只要给定的testing方法完成,XCTest方法将考虑完成一个testing,并转到下一个testing。 这意味着在下一次testing运行时,来自以前testing的任何asynchronous代码将继续运行。 networking代码通常是asynchronous的,因为您不想在执行networking提取时阻止主线程。 再加上当testing方法结束时testing完成的事实,可能使testingnetworking代码变得困难。“ 不过,这在我看来是矛盾的。 如果我的理解正确,他说,即使asynchronous代码完成,XCTest方法也会继续运行。 然而,他接着说testing方法完成后testing就完成了。 但是这两个语句是矛盾的,由于asynchronous代码仍在运行,testing没有完成,而是在串行队列中继续执行下一个进程。 换句话说,当asynchronous代码完成时testing是否完成,还是在asynchronous代码仍在运行时继续testing? 最重要的是,networkingtesting如此困难? 谢谢。

NSManagedObjectContext的performBlockAndWait:不在接收者的队列上执行

我注意到NSManagedObjectContext和NSMainQueueConcurrencyType NSManagedObjectContext执行NSMainQueueConcurrencyType :并且在接收者(主)队列以外的队列上执行该块。 例如,如果我的parentContext的types为NSMainQueueConcurrencyType并且我的childContext的types为NSPrivateQueueConcurrencyType ,那么下面的代码将导致我的parentContext执行childContext的队列上的块: [childContext performBlockAndWait:^{ //Thread 1, Queue: NSManagedObjectContext Queue [parentContext performBlockAndWait:^{ //Thread 1, Queue: NSManagedObjectContext Queue //This is the same queue as the child context's queue }]; }]; 相反,下面的代码按预期工作 – 我的parentContext执行主队列上的块: [childContext performBlock:^{ [parentContext performBlockAndWait:^{ //Thread 1, Queue: com.apple.main-thread }]; }]; 这是预期的行为? 由于docs的状态为"performBlockAndWait: synchronously performs a given block on the receiver's queue."所以这当然令我感到困惑"performBlockAndWait: […]

dispatch_once过度杀伤了+ ?

如果我在+[NSObject initialize]里面创build一个单例,我需要把我的代码放在dispatch_once块里面吗? static NSObject * Bar; @implementation Foo + (void)initialize { if (self == [Foo class]) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Bar = [NSObject new]; }); } } @end 编辑 我很担心这一点,因为我想确保所有的线程都会在调用+[Foo initialize]之后看到我已经设置了Bar 。 文档说+[NSObject initialize]是线程安全的,但这是否意味着它是内存安全的?

SQLite错误:EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,subcode = 0x0)-iOS

当我试图插入数据到我的表,有时我得到这个错误,我的应用程序崩溃! 请先解决我的问题。 崩溃日志: Observation(4001,0x10dd67000) malloc: *** error for object 0x7fff3a917100: Non-aligned pointer being freed (2) *** set a breakpoint in malloc_error_break to debug 2016-11-03 11:12:03.063 Observation[4001:46477] Insertion failed ! Printing description of dbpath: (const char *) dbpath = 0x00007fff3b8a5690 "/Users/macbt/Library/Developer/CoreSimulator/Devices/0EEC62AE-6DF0-4FC4-9D30-1EB90CB695A5/data/Containers/Data/Application/A709E729-3162-4CC8-B9FF-2F22A32FC6BD/Documents/ObservationDB.db" Printing description of insertSQL: insert into table_hazard (id, name, modifiedDate) values ("1","Hazard", "03/11/2016 11:12:03 AM") […]

加载UIImagePickerController更快?

我需要加载UIImagePickerController更快。 我的应用程序将从可能的多个控制器调用UIImagePickerController ,并在每个控制器中有两个button,一个用于照片库,另一个用于相机。 这是我的示例应用程序。 我尝试过的一些解决scheme是Apple在“ 并发编程指南 ”中推荐的。 最简单的是当用户按下button时,分配&init实例。 相机出现之前最多可能需要2秒钟的时间。 解决scheme尝试: – (1)我做了一个@property(…)* imagePicker,并在viewDidAppear调用它的alloc&init来使它看起来很stream畅,但是它妨碍了加载其他元素,可能是因为它使用了同一个线程。 在initWithNibName或viewDidLoad使用时会导致较差的结果。 (2) Operation queues …不令人满意的结果。 (3) Dispatch Queues …更好的结果,但仍然明显的波涛汹涌的performance。 (4) performSelectorInBackground:withObject:不是很好的结果。 除非另有build议,否则我不认为我想走向世界。 我没有任何问题,使两个@properties的UIImagePickerController 。 我将继续可能的' 线程编程指南 '。 如果可以的话,请在您的解决scheme中包含任何必要的内存pipe理实践。 谢谢。 – (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // (1) TRYING OPERATION QUEUES // (a) — NSBlockOperation NSBlockOperation *NSBO_IP = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"before"); imagePicker = [[UIImagePickerController […]

在UITableView上执行GCD

当我创build单元格时,我正在进行一些繁重的计算。 我试图找出保持UITableViewstream体的最佳方式,但是在相同types的背景上进行计算(保持UI线程没有太多的处理)。 仅用于testing目的,我使用这个作为我繁重的计算方法: +(NSString*)bigCalculation { int finalValue=0; int j=0; int i=0; for (i=0; i<1000; i++) { for (j=0; j<10000000; j++) { j++; } finalValue+=j/100*i; } return [NSString stringWithFormat:@"%d",finalValue]; } 在cellForRowAtIndexPath里面,我只做下面的事情: – (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *identifier=@"identifier"; UITableViewCell *cell=nil; cell=[aTableView dequeueReusableCellWithIdentifier:identifier]; if(!cell) { cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier]; } NSString *text=[dataSource objectForKey:[[dataSource allKeys] objectAtIndex:indexPath.row]]; […]

global_queue与qos_class_user_interactive

我尝试了解GCD并编写了这个代码来找出运行优先级: override func viewDidLoad() { super.viewDidLoad() fetchImage() print(1) dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { print(2) } dispatch_async(dispatch_get_main_queue()) { print(3) } dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0)) { print(5) } } 我在控制台中得到了下一个结果: 1 2 五 3 所以问题是: 第1部分 :为什么3是5之后(main_queue具有最高优先级?) 第二部分 :为什么2比3和5要高? 感谢你们!

Swift 3 GCDlockingvariables和block_and_release错误

我正在使用Swift 3 GCD来执行我的代码中的一些操作。 但是我经常遇到_dispatch_call_block_and_release错误。 我想这个错误背后的原因是因为不同的线程修改相同的variables,但我不知道如何解决问题。 这是我的代码和解释: 我有一个variables在不同的线程中被访问和修改: var queueMsgSent: Dictionary<Date,BTCommand>? = nil func lock(obj: AnyObject, blk:() -> ()) { objc_sync_enter(obj) blk() objc_sync_exit(obj) } func addMsgSentToQueue(msg: BTCommands) { if queueMsgSent == nil { queueMsgSent = Dictionary.init() } let currentDate = Date() lock(obj: queueMsgSent as AnyObject) { queueMsgSent?.updateValue(msg, forKey: currentDate) } } func deleteMsgSentWithId(id: Int) { if […]

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,或者沿着这些线? 寻找大素数? […]

在当前队列上同步分派

我知道你可能会发现这是一个奇怪的问题,但我只是学习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代码?