Tag: multithreading

如何在后台线程上高效地写入大文件到磁盘(Swift)

更新 我已经解决并删除了分心的错误。 如果还有任何问题,请阅读整篇文章,随时留下意见。 背景 我试图在iOS上使用Swift 2.0,GCD和完成处理程序将相对较大的文件(video)写入磁盘。 我想知道是否有更有效的方法来执行这项任务。 该任务需要在不阻塞主UI的情况下完成,同时使用完成逻辑,并确保操作尽可能快。 我有一个NSData属性的自定义对象,所以我目前正在NSData上使用扩展实验。 作为一个例子,备用解决scheme可能包括使用NSFilehandle或NSStreams以及某种forms的线程安全行为,从而比基于当前解决scheme的NSData writeToURL函数产生更快的吞吐量。 无论如何,NSData有什么问题? 请注意以下从NSData类参考( 保存数据 )的讨论。 我执行写入我的临时目录,但是我有一个问题的主要原因是,我可以看到在处理大型文件时在UI中明显的滞后。 这种滞后正是因为NSData不是asynchronous的(Apple Docs注意到primefaces写入会导致“大”文件的性能问题〜> 1mb)。 所以当处理大文件时,任何内部机制在NSData方法中都是有效的。 我做了一些更多的挖掘,并从苹果发现这个信息…“这种方法是理想的转换数据:/ / URL到NSData对象,也可用于同步阅读短文件如果您需要阅读可能的大文件 ,使用inputStreamWithURL:打开一个stream,然后一次读取一个文件。“ ( NSData类参考,Objective-C,+ dataWithContentsOfURL )。 这个信息似乎意味着如果将writeToURL移动到后台线程(如@jtbandes所build议的)是不够的,我可以尝试使用stream将文件写入后台线程。 NSData类及其子类提供了快速方便地将其内容保存到磁盘的方法。 为了尽量减less数据丢失的风险,这些方法提供了primefaces保存数据的选项。 primefaces写保证数据要么全部保存,要么完全失败。 primefaces写入通过将数据写入临时文件开始。 如果写入成功,则该方法将临时文件移动到其最终位置。 尽pipeprimefaces写入操作可以最大限度降低由于损坏或部分写入的文件而导致数据丢失的风险,但在写入临时目录,用户的主目录或其他可公开访问的目录时,它们可能并不合适。 任何时候您使用可公开访问的文件时,都应该将该文件视为不可信且潜在危险的资源。 攻击者可能会妥协或损坏这些文件。 攻击者也可以使用硬链接或符号链接replace文件,导致写操作覆盖或损坏其他系统资源。 在可公开访问的目录中工作时,避免使用writeToURL:atomically:方法(和相关的方法)。 而是使用现有的文件描述符来初始化NSFileHandle对象,并使用NSFileHandle方法来安全地写入文件。 其他select 关于并发编程objc.io上的一篇文章提供了有关“高级:背景下的文件I / O”的有趣选项。 一些选项也涉及到使用InputStream。 苹果公司也有一些旧的引用来读取和写入文件asynchronous 。 我正在发布这个问题,预计Swift的替代品。 一个合适的答案的例子 下面是可能满足这类问题的适当答案的一个例子。 (采取stream编程指南, 写入输出stream ) 使用NSOutputStream实例写入输出stream需要几个步骤: 用写入数据的存储库创build并初始化一个NSOutputStream的实例。 […]

核心数据更改不合并

我已经build立了一个非层次的双MOC架构(一个用于主线程,一个用于私有线程),并具有保存通知用于合并更改: – (NSManagedObjectContext *)managedObjectContext { if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { NSManagedObjectContext* mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [mainContext setPersistentStoreCoordinator:coordinator]; [mainContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; _managedObjectContext = mainContext; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSaveMainQueueContext:) name:NSManagedObjectContextDidSaveNotification object:_managedObjectContext]; } return _managedObjectContext; } – (NSManagedObjectContext *)privateManagedObjectContext { if (_privateManagedObjectContext != nil) { […]

在后台线程中加载UIImage

是否有可能在后台线程中加载UIImage而不会导致线程问题? 如果不是这样做的最好方法是什么? 我正在使用iOS 8.这是我现在这样做的方式: dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); dispatch_async(backgroundQueue, ^{ UIImage *image = [UIImage imageNamed: fileName]; // only update UI on the main thread dispatch_async(dispatch_get_main_queue(), ^{ [self setImage: image]; }); });

iPhone 4有一个绝对确定的方式来长期NSTimer火灾

我一直有我的NSTimers和背景select器的麻烦。 这是让我疯狂,需要很长时间来尝试每一个调整。 为了保持我的理智,以及后代cocoa程序员的理智,我问了这个问题: 有一个绝对100%的可靠的方法来让一个定时的,长期的计时器在晚些时候触发,而不pipe它是从后台线程,主线程等调用的吗? 似乎我一直都不得不一遍一遍地解决使用NSTimers的大多数类的相同的问题。 他们在短期testing期间工作,比方说,我设置定时器通过后台线程在10秒内触发。 它工作,因为仍然有运行循环运行。 但是,一旦我把火灾时间改变到了我真正想要的时间,比如15-30分钟,就有了沉默。 运行循环已经结束,我不知道如何处理这种情况。 什么都没有发生,几天后我发现了这样的错误,一旦我已经忘记了哪个计时器会对此负责。 目前,我正在用select器做一些非常非常难看的舞蹈,例如这里有一个testing方法(它似乎适用于10分钟的定时器): //this is a test method to simulate a background task requesting a timer [self performSelectorInBackground:@selector(backgroundReminderLongTermTest:) withObject:nil]; //this is a method similar to the one that the background thread would be trying to invoke -(void)backgroundReminderLongTermTest:(id)sender { [self performSelectorOnMainThread:@selector(backgroundReminderFromMainThread:) withObject:nil waitUntilDone:NO]; } //this is a wrapper […]

– 只能从主线程调用

这个警告导致了一个严重的问题,因为我真的不能使用Xcode 9 beta 2调用主线程之外的委托。奇怪的是,当我使用Xcode 8.3.3时,这是工作。 我还认为只从主线程调用代表只是一个好习惯,不是吗? 那么为什么这会导致应用程序崩溃呢?

iOS:错误__connection_block_invoke_2:连接中断

控制台中的Xcode / iOS 8 / AVFoundation相关的错误: error in __connection_block_invoke_2: Connection interrupted 我只是将AVCaptureVideoDataOutput添加到苹果的示例应用程序“AVCamManualUsingtheManualCaptureAPI” 我补充说的是: // CoreImage wants BGRA pixel format NSDictionary *outputSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithInteger:kCVPixelFormatType_32BGRA]}; // create and configure video data output AVCaptureVideoDataOutput *videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; videoDataOutput.videoSettings = outputSettings; videoDataOutput.alwaysDiscardsLateVideoFrames = YES; [videoDataOutput setSampleBufferDelegate:self queue:sessionQueue]; 上面的代码插入到示例项目中: – (void)viewDidLoad { [super viewDidLoad]; […]

安全的方式来渲染UIVIew后台线程上的图像?

我创build的小瓷砖图像存储在磁盘上并显示给用户。 这是我现在这样做的过程: 创build一个代表我想在屏幕上显示的用户界面的视图控制器 从视图控制器获取视图并从中呈现图像 将其保存到磁盘并稍后在屏幕上显示 当我尝试访问viewcontroller的视图时,我崩溃。 当我试图在网上进行研究的时候,在后台创build视图是否安全,我得到了相互矛盾的结果。 我读的UIGraphicsGetCurrentContext调用应该是线程安全的,但也许不访问后台线程上的UIView? 我正在为iOS 4及以上版本编写应用程序。 这里是我使用的代码(平铺是视图控制器): CGSize size = CGSizeMake(20.0f, 30.0f); UIGraphicsBeginImageContext(size); [tile.view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 尝试访问图块上的.view属性(EXC_BAD_ACCESS)时发生崩溃。 整个过程是在后台渲染视图以防止lockingUI,因为有大量的图块需要处理。 有没有安全的方法来做到这一点?

NSFetchedResultsController:在后台线程中获取

我有一个或多或less的基本UITableViewController NSFetchedResultsController 。 UITableViewController被推到navigationController's堆栈上。 但是推animation并不stream畅,因为NSFetchedResultsController的获取是在主线程上执行的,因此阻塞了UI。 我的问题是:如何在后台线程中执行NSFetchedResultsController的获取以保持animation的平滑? NSFetchedResultsController和委托方法如下所示: – (NSFetchedResultsController *)fetchedResultsController { if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; // Edit the entity name as appropriate. NSEntityDescription *entity = [NSEntityDescription entityForName:@"GPGrade" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; // Set the batch size to a suitable number. [fetchRequest setFetchBatchSize:20]; //Set predicate NSPredicate *predicate […]

提升线程:在IOS中,thread_info对象在线程完成执行之前被破坏

我们的项目在几个平台上使用了几个增强的1.48库,包括Windows,Mac,Android和IOS。 当我们使用IOS的时候,我们能够始终如一地获取项目的IOS版本(非常规但可靠地)崩溃,并且从我们的调查中我们看到〜thread_data_base在线程仍在运行时正在线程的thread_info上被调用。 这似乎是智能指针达到零计数的结果,尽pipe它显然仍在thread_proxy函数的作用域中,该函数创build它并在线程中运行所请求的函数。 这似乎在各种情况下发生 – 调用堆栈在崩溃之间并不相同,尽pipe有一些常见的变化。 只需要清楚一点 – 这通常需要运行代码来创build数百个线程,但同时运行的却不会超过30个。 我很幸运,在运行中也很早,但这很less见。 我创build了一个实际上可以捕获代码的析构函数的版本: 在libs / thread / src / pthread / thread.cpp中: thread_data_base::~thread_data_base() { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); void *void_thread_info = (void *) thread_info; void *void_this = (void *) this; // is somebody destructing the thread_data other than its own thread? // (remember that its own which should […]

“Apple Mach-O链接器命令失败,退出代码1”

我正在尝试实施SVProgressHUD活动指标。 我将这些类复制到我的项目中,并将下面的代码添加到我的appDelegate,但无法弄清楚为什么它崩溃。 我得到他们以下错误,我不知道在哪里可以修复它: Undefined symbols for architecture i386: "_OBJC_CLASS_$_SVProgressHUD", referenced from: objc-class-ref in QuotesAppDelegate.o ld: symbol(s) not found for architecture i386 clang: error: linker command failed with exit code 1 (use -v to see invocation) 这里是代码: #import "SVProgressHUD.h" @implementation QuotesAppDelegate – (void)startLoading { //call this in your app delegate instead of setting window.rootViewController to your […]