Tag: multithreading

为核心数据写入创build后台线程

我试图重新创build本cocoa系统文章( http://www.cocoanetics.com/2012/07/multi-context-coredata/ )中描述的三层核心数据系统。 我遇到的问题是在自己的后台线程上创build私有MOC。 我没有太多的multithreading经验,应该如何在目标c中完成。 我一直在阅读文章,并试图如何正确地实施这个方法,但我终于承认,我不知道我在做什么。 要创build这种方法,我需要创build一个NSThread并进行pipe理吗? 还是有一种更简单的方式,我不理解?

核心数据:父上下文阻止孩子

我正在做一些有核心数据的应用程序的后台处理。 后台处理是在一个子managedObjectContext上完成的。 上下文初始化 appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate // the moc in appDelegate is created with .MainQueueConcurrencyType mainThreadMOC = appDelegate.managedObjectContext! backgroundMOC = NSManagedObjectContext(concurrencyType:NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType) backgroundMOC?.parentContext = mainThreadMOC 后台处理按以下方法完成: // download all new transaction log entries func syncItems() { … set up the query object for parse let moc = CoreDataStore.sharedInstance.backgroundMOC // perform download moc?.performBlock( { self.runQuery(query) […]

Swift – 是懒惰的线程安全?

也许这个问题需要一些背景。 我一直在使用Core Data处理持久层,并发现Core Data不是线程安全的,因此NSManagedObjectContext只能被限制在每个线程中。 所以我的方法是创build自定义后台线程NSManagedObjectContext执行获取,保存等,同时也创build主线程NSManagedObjectContext将用于NSManagedObject获取NSManagedObjectId并将其传递给调用方法。 默认情况下,Xcode使用lazy var为所有NSManagedObjectContext , NSManagedObjectModel等生成与Core Data相关的模板代码。 所以我的问题是是否要 使用lazy var实例化方法来创buildNSManagedObjectContext ,只要lazy var为每个试图访问的线程启动一个对象(不是线程安全的?) 要么 在每个线程中为NSManagedObjectContext声明单独的variables,并使所有线程相关的方法引用两个不同的NSManagedObjectContext前提是lazy var是线程安全的(?),并且在被访问时只创build一次而不pipe线程。 先谢谢你! 编辑:任何正在为核心数据并发问题而苦恼的人, 本文列出了一个非常好的devise模式,正如Aaron在下面的评论中指出的那样!

顶点数组对象(VAO)可以在OpenGL ES的EAGLContext中共享吗?

扰stream板:我相当有信心,答案是NO ,但这只是一个非常沮丧的debugging后一天。 现在我想知道这是否确实如此(如果是这样,我可能已经知道了),或者我只是在做一些完全错误的事情。 这是情况。 我正在使用OpenGL ES 2.0来呈现从各种文件(.obj,.md2等)加载的一些网格。 为了性能和用户体验,我使用GCD将这些网格及其关联纹理的实际加载委托给后台线程。 根据Apple的 说明 ,在每个后台线程上,我使用与主渲染上下文相同的shareGroup创build并设置了一个新的EAGLContext。 这允许在后台线程上创build的OpenGL对象,如纹理和缓冲区对象,被主线程上下文立即使用。 这一直是出色的。 现在,我最近了解到顶点数组对象是一种caching与渲染某些缓冲区内容相关的OpenGL状态的方法。 它看起来不错,并减less了样板状态检查和设置渲染每个网格所需的代码。 最重要的是,苹果公司还build议在“ 使用顶点数据的最佳实践指南”中使用它们。 但是我有严重的问题让VAO为我工作。 就像我所有的加载,我会加载网格从一个文件到后台线程的内存,然后生成所有相关的OpenGL对象。 没有失败,我第一次尝试使用VAO调用glDrawElements() ,该应用程序崩溃与EXC_BAD_ACCESS 。 没有VAO,它渲染罚款。 debuggingEXC_BAD_ACCESS是一件很痛苦的EXC_BAD_ACCESS ,特别是当NSZombies不会帮助的时候(他们显然不会这么做),但是在分析捕获的OpenGL帧之后,我意识到,在后台线程创buildVAO的时候没有问题GL_ERROR和一个非零的id),当时间绑定到主线程上的VAO,我会得到一个GL_INVALID_OPERATION ,当试图绑定到一个不存在的VAO时,文档状态将会发生。 当然,在渲染时查看当前上下文中的所有对象时,不会看到单个VAO, 但是所有在同一时间内由VAO生成的VBO都存在 。 如果我在主线程加载VAO,它工作正常。 非常令人沮丧。 我将加载代码提炼成更primefaces的forms: – (void)generate { glGenVertexArraysOES(1, &_vao); glBindVertexArrayOES(_vao); _vbos = malloc(sizeof(GLuint) * 4); glGenBuffers(4, vbos); } 当在后台线程上执行上述操作时,使用与主要上下文具有相同shareGroup的有效EAGLContext ,主要上下文将有4个VBO,但不包含VAO。 如果我在主线上执行它,主要内容是4个VBO和VAO。 这使我得出这样的结论:在处理VAO时,EAGLContext的对象共享特性存在一些奇怪的例外。 如果真的是这样的话,我真的希望苹果的文档在某处注意到。 手工发现这些小花絮是非常不方便的。 这是这种情况,还是我错过了什么?

重入读/写locking结构?

我是一名经验丰富的.NET程序员,用iOS来伸展我的双腿。 在.NET中我最喜欢的multithreading构造是ReaderWriterLock 。 它允许多个读者或一个作家。 我真的在iOS中缺less的一个特点是锁是可重入的。 也就是说, 读者线程只要释放相同的次数就可以多次获取读锁 。 同样,只要单个写入器线程释放locking数量相同,就可以多次获取locking。 我研究过iOS框架,并没有一个构造似乎提供了相同的支持,包括重入性。 我也看了一下pthread库。 我发现了rwlock,但是它不允许重新进入。 iOS上有什么允许重入读写锁的东西?

如果setKeepAliveTimeout方法设置15分钟,VOIP应用程序不能及时唤醒

我开发的应用程序应该每15分钟处理一些数据。 所以我添加了voip标志到plist文件中。 并使用900秒(15分钟)setKeepAliveTimeout。 还添加了处理某些数据的后台任务function。 处理数据最多需要10秒。 问题是,应用程序不及时醒来。 有时12分钟后,有时16分钟后等,但我需要15分钟。 如何解决以下问题? iOS版本是5.0+ 如果是iOS的具体请提供我官方参考苹果的API文件,这里提到。

Sprite Kit中可重复使用的multithreading实现

我正在做一个Sprite Kit游戏,我需要做一些multithreading来保持健康的fps。 在更新时,我调用一个函数来创build大量的UIBezierPaths,并使用C ++静态库合并它们。 如果我有超过10个形状的帧速率急剧下降,所以我决定给GCD尝试并尝试用单独的线程来解决这个问题。 我把这个放在didMoveToView: queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); 并在每帧被调用的函数中,我称之为: dispatch_async(queue,^(void){[self heavyCalculationsFunc];}); 对于那些了解GCD的人来说,这可能是显而易见的,它会在每个框架上创build一个新的线索,但是对于我来说还不清楚。 我的问题是,是否有任何方法来重新使用我想调用更新的线程? 感谢您的帮助提前!

检测背景中的可达性

我一直在testing不同的方式来实现的可能性,以知道设备上网时,它的应用程序是在后台,所以我testing的第一个代码是苹果的可达性示例代码http://developer.apple.com/library/ios /#samplecode/Reachability/Introduction/Intro.html 但是这个代码在后台应用程序中不会通知互联网状态。 所以我也尝试了下面的代码,当App从Background状态启动到前台时(与Apple可达性示例代码相同) – (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // check for internet connection [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil]; // Set up Reachability internetReachable = [[Reachability reachabilityForInternetConnection] retain]; [internetReachable startNotifier]; … } – (void)applicationDidEnterBackground:(UIApplication *)application { // check for internet connection [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil]; // Set up Reachability internetReachable = […]

为什么在处理主线程上的大量任务时,NSOperationQueue比GCD或者performSelectorOnMainThread更快?

例如,我有100次for循环。 并需要更新UIImageView,最后2种方法是一样的慢。 为什么? 他们之间有什么不同? //fastest [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal]; [scrollView addSubview:btnThumb]; }]; //slowly dispatch_async(dispatch_get_main_queue(), ^ { [btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal]; [scrollView addSubview:btnThumb]; }); //slowly [btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal]; [self performSelectorOnMainThread:@selector(testMethod:) withObject:[NSArray arrayWithObjects:scrollView, btnThumb, nil] waitUntilDone:NO]; -(void) testMethod:(NSArray*)objs { UIScrollView *scroll = [objs objectAtIndex:0]; UIButton *btn = [objs lastObject]; [scroll addSubview:btn]; }

在不同的线程上调用我的方法有哪些不同的方法?

我有一些数据计算方法(让它是“myMethod:”),我想移动到另一个线程的调用,因为我不想阻止我的主要用户界面function。 所以,开始做一些关于如何在另一个线程上调用我的方法的研究。 据我所知,目前有很多不同的方法来做到这一点。 这是一个列表: a)使用纯线程(可用于iOS 2.0): [NSThread detachNewThreadSelector:@selector(myMethod:) toTarget:self withObject:_myParamsArray]; b)使用简单的快捷方式(从iOS 2.0开始可用)。 可用于inheritance的NSObject,但该方法也属于NSThread类: [self performSelectorInBackground:@selector(myMethod:) withObject:_myParamsArray]; c)使用Grand Central Dispatch队列的新方法(从iOS 4.0开始): dispatch_async(dispatch_get_global_queue(0, 0), ^ { [self myMethod:_myParamsArray]; }); d)不知何故,使用一些类,如NSOperation,NSBlockOperation或NSOperationQueue,虽然不知道该怎么做(一些例子,将不胜感激) 目前,我曾经用过“b”这个案例,但是对这个利弊感兴趣,还有其他相关的build议。 更新:e)也发现了另一种执行类似线程的东西 – 运行循环 。 以下是苹果文档摘录: 运行循环是一个事件处理循环,用于安排工作和协调收到的事件。 运行循环的目的是在有工作要做的时候保持你的线程忙,当没有时候让线程进入睡眠状态。 恕我直言,或多或less你正在处理相同的任务 – 如何调用你的方法在单独的线程进行asynchronous操作。 更新2:已经有了NSInvocationOperation和NSOperationQueue和恕我直言的一些经验,这是相当方便的。 根据苹果文档,GCD和NSOperations是实现multithreading的首选方式。 而且,NSOperations从iOS 4.0开始运行在GCD上。 简而言之,你实例化NSIvocationOperation(作为你的方法的调用),然后实例化NSOperationQueue并将调用添加到队列中。 NSOperationQueue足够聪明,你可以将多个NSIvocationOperation对象(包装你的方法调用)和它们实例化到NSOperationQueue。 剩下的就放心了。 NSOperationQueue确定需要多less个并行线程来执行调用(NSInvocationOperation)并为您处理。 它可以在线程A上执行第一个调用,然后在线程B上执行第一个调用,在线程C上执行第三个,然后执行在线程B上,所以你不必担心这个问题。 但是,如果你想,你可以告诉NSOperationQueue最大的线程可以用来执行调用(例如1),但我没有这个需要。 默认情况下,所有的任务都是在主线程以外的地方执行的,所以操作队列默认是asynchronous的。 另外,如果你想在一个严格队列中执行你的方法调用(每个包装在单独的NSInvocationOperation中),那么你可以添加依赖关系,所以NSOperationQueue将保留方法调用顺序。 这是一个例子: // wrap your […]