问题标签 [nsoperation]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
279 浏览

iphone - 为什么 iPhone OS 3.1 上的 NSOperationQueue 会保留长期取消(和释放)的操作?

我有一个NSOperations用于管理对 Web API 的服务调用的应用程序(这些调用基于Jon Wight 的 touchcode 中的 CURLOperation)。

当地图视图的中心发生显着变化时,有一个下载地图位置的调用;因为这些可以很快堆积起来,如果你移动地图,我会尝试积极取消过时的操作。它在 4.0 上运行良好。

但是,在 3.1 上,似乎在某些情况下操作队列将保留已取消(和已释放)的操作,当它到达它们应该在队列中的位置时会导致崩溃。

这是一个插图。

我从队列中一个相对重量级的服务调用开始:

  1. MyLongRunningOp 0x1

用户导航到地图。队列现在看起来像这样:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x2

他们移动地图,取消 MyMapOp 0x2 并添加 MyMapOp 0x3:

  1. MyLongRunningOp 0x1
  2. MyMapOp 0x3

MyMapOp 0x2现在已释放,因为它已从队列中删除。现在MyLongRunningOp 0x1结束。在设置 isFinished 键的 KVO 回调中MyLongRunningOp,我看到操作队列处理通知并尝试将其添加MyMapOp 0x2到一些NSArray. 自然,NSZombies启用后,

似乎它以NSOperationQueue某种方式挂在指向取消/释放操作的指针上,并在先前的操作完成后尝试激活它。

我无法在 4.0 上重现这种行为,所以我相信这是 3.1 的错误。

我在解决它时遇到了很多麻烦——据我所知,唯一的解决方法是永远不要取消我的操作,这会在网络变得不稳定时造成次优体验。

有没有其他人经历过这个?有任何想法吗?

0 投票
1 回答
2950 浏览

iphone - iPhone / iOS popViewControllerAnimated 不刷新屏幕

.navigationController popViewControllerAnimated:YESNSOperation屏幕未正确更新并使弹出视图可见但显然已解除分配的位置调用时,我遇到了一个奇怪的问题。

详细信息:我有一个访问本地sqlite数据库的列表视图。当点击一条记录时,它会显示该记录的详细视图并启动一个异步 NSOperation(在主线程上)以检查 XML 后端数据库以查看该记录在数据库中是否仍然可用。由于架构原因,我不会进入,我无法在列表视图上运行此操作,它必须在详细视图中。如果自上次同步后删除了记录,它会通知用户该记录已被删除,并popViewControllerAnimated在共享应用程序委托上调用。理想情况下,这将弹出当前详细视图并返回到先前的列表视图。

错误:正确的视图实际上已在内存中弹出(已被释放),但仍显示在屏幕上。导航栏是空白的,但我可以点击“返回”按钮应该在的位置,它会在列表视图之前导航到开始屏幕,这意味着至少导航栏知道它应该在哪里,甚至如果它没有正确显示标题或后退按钮。主要问题是详细视图仍然可见并且可以与之交互,这会导致应用程序崩溃。例如,详细视图还显示 a 中的数据UITableView,如果用户在表格中向下滚动,则会引发异常“-[xAccountDetailController tableView:cellForRowAtIndexPath:]:消息已发送到已释放实例”

这让我相信细节控制器已经被popViewControllerAnimated调用正确地释放了,但是如果表实际上调用了,那么显然有些东西仍然驻留在内存中cellForRowAtIndexPath,即使它的视图控制器已经从导航控制器中弹出。

在“详细信息”视图中手动按下后退按钮(对于未在后端删除的记录)效果很好。

解决方法尝试:当我向 NSOperation 传递对详细视图控制器的引用时,我试图popViewControllerAnimated直接从该视图的 navigationController 属性和共享应用程序委托调用。我还尝试弹出两个视图并将列表视图重新推送到 navigationController 上,但这会带来更令人不安的界面效果,其中根视图控制器和列表视图控制器似乎同时存在于导航栏中(标题相互覆盖而不是不存在)。我试图将 NSOperation 中存在的详细视图控制器的引用设置为 nil,但这没有任何作用。我尝试[detailView release]在弹出之前调用 a ,但正如预期的那样,它在弹出时失败,因为它在发布之前只有 1 的保留计数。我'popToViewController而且popToRootViewController似乎没有任何效果。旧视图始终存在,导航栏是唯一似乎可以做任何事情的界面元素,即使那样,它也显示不正确。我也尝试过重新加载表格,因为我真的不介意视图是否保持可见(没有弹出),我只想清除数据——但表格由于某种原因不会重新加载数据。

想法:由于运行 NSOperation 的 operationQueue 是相关详细视图的属性,因此我确保在详细视图的 dealloc 中取消所有操作并将对 operationQueue 的引用设置为 nil。我还尝试确保其他对象中对该视图的所有引用都设置为 nil。直接从详细视图上的按钮调用popViewControllerAnimated可以完美运行,所以一定是我从 NSOperation 调用该方法,在 NSOperationQueue 上运行,这是我想要弹出的详细视图的属性。某处的某些引用必须使该视图部分保持活动状态,但是当调用 pop 时,我似乎找不到任何仍在引用该视图的内容。

太多地方的代码太多了,无法在这里发布。

有什么想法吗?

抱歉问了这么长的问题,提前谢谢,

格雷格


编辑 1:我可以使用新的 UIViewController 在 NSOperation 之外轻松重现此问题。

在一种tableView:didSelectRowAtIndexPath方法中,我调用以下内容:

在vc中,popView方法:

我认为这与保留计数或 NSOperation 无关。以这种方式弹出视图,我在做一些根本错误的事情吗?

0 投票
1 回答
383 浏览

iphone - NSOperation(s) 仅在 iOS 3 设备上泄漏

我有一些处理 CoreData 导入的 NSOperations 子类。我相信我已经勾选了大多数非主线程问题

  • main我在方法中创建了自己的自动释放池
  • NSManagedObjectContext我为每个操作创建一个

这些操作被加载到一个 NSOperationQueue 中,最大并发操作数设置为 1。

该代码在 iOS 4.0.1 上完美运行,但在 iOS 3.1.3 设备上会收到大量日志消息,如下所示

NSOperation 子类主方法

__lookup:inContext:方法_

大多数其他方法的实例方法,即threadContext看起来与__lookup:inContext:方法相似。我知道我不会为实例方法创建 Autorelease 池,但根据我对 autorelease 工作原理的理解,只要这些方法仅在 main 方法内部调用,在NSAutoreleasePool创建之后,最外层池应该使用。我懒惰地创建诸如 NSManagedObjectContext 之类的对象,并且在大多数情况下不使用该start方法

0 投票
1 回答
199 浏览

multithreading - 如何让我的应用程序响应更快?

背景

这与我上一个问题的背景相同,除了大纲视图没有提取谓词。

  • 我有一个NSOutlineView显示 TrainingGroup 实体的。

  • NSOutlineView绑定到一个NSTreeController

  • 在 NSTreeController 中,我勾选了“保留选择”和未勾选“选择插入的对象”。

  • 每个 TrainingGroup 代表本地机器上的一个文件夹。

  • 每个 TrainingGroup 都可以分配给一个项目。该项目应传播到该组的所有后代。

  • 项目列绑定到每个训练组的项目属性。

  • 这个视图中有很多数据。因为每个条目都有一个条目,所以在一个训练视图下总共可以有 ~15000 个后代。

大纲视图

树看起来像这样:

在项目分配上

  • 编辑项目时,所有子类的分配发生在NSOperation后台线程的子类上,因此用户可以自由地进行其他选择并在处理所有子类的同时四处移动。

  • 操作完成后,我mergeChangesFromContextDidSaveNotification:在主托管对象上下文中运行该方法:

    mainContext = [[NSApp delegate] managedObjectContext]; [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES];

  • 从功能上讲,这工作正常 - 当上下文合并回主时,所有后代都分配给项目。

问题

  • 在合并时,NSOutlineView绑定到主上下文的那个会冻结,合并可能需要几秒钟才能完成。

  • 为了减少这种冻结,我将这些组分批分配到几个较小的操作中。

这种批量后台操作方式存在三个问题:

  1. 界面在几分之一秒内变得无响应。这没什么大不了的,但它确实意味着界面中有一些不可预测的小停顿。

  2. 大纲视图会更新合并回来的每个批次。这样做时,选择可能会出现故障。

  3. 分配组下的一些项目保持空白。对象已分配项目,但大纲视图未正确刷新项目。大概是因为主线程被合并打断了。

您可以在我录制的截屏视频中看到这些问题:

http://screenr.com/Fk4

替代方案

我可以将每个操作的更改合并到在后台线程上运行的托管对象上下文中。他们也许我可以向主线程发送一条消息以刷新已更改的顶级组中的所有对象。

这可能会摆脱上面的问题 1 和 3,但我认为 2 仍然是一个问题。

我的问题

有没有更好的方法来做到这一点?

在我开始重新设计我如何做到这一点之前(我已经改变了它的工作方式一次)我想知道是否有更好的方法或者这种方法有什么我不知道的缺点。

提前感谢您对替代品的任何建议。

0 投票
3 回答
2511 浏览

iphone - 带有 NSOperations 的 iOS 应用架构

两个月前,我开始编写一个新的 iPhone 应用程序,为此我创建了一个通用的 RESTFul Web 服务,它允许我拥有许多这些必要的功能,例如用户身份验证、用户配置文件、友谊系统、媒体处理、消息传递系统等等。在我看来,有几个用例可以将这个 Web 服务重用于未来的 iPhone 应用程序。

带着这种心态,我决定为这个应用程序(以及所有未来的应用程序)编写一个静态库,以处理所有繁重的工作,如媒体(图像、视频、声音)设置和处理、与 Web 服务通信、解析和映射结果,处理CoreData等。

鉴于我的应用程序有很多并行任务正在运行(最坏情况)的场景,例如用户当前更改了他/她的个人资料图片,而应用程序将用户位置发送到服务器(在后台)并且新的推送通知是已收到。

因此决定将每个逻辑操作(如 SendUserLocation 或 GetCurrentFriendList)封装在一个 NSOperation 中,并将它们添加到一个服务队列(NSOperationQueue)中。

当操作成功地从 web 服务获得结果并且现在应该处理它时,每个操作都能够产生子任务。

替代文字

一个典型的 ServiceManager 方法看起来像

每个操作、请求(对服务器)和 subTask 都使用 GUID 作为 notificationName,以在完成处理时通知父对象。如果操作中的所有内容都已完成,它会将通知发送回用户界面。

也就是说,添加和删除子任务的代码如下所示

现在我所要做的就是在我的 gui 中调用 serviceManager 来启动一个特定的操作,比如

如果我想注册一个观察者,我只需传递一个观察者对象和一个像这样的选择器

最后但并非最不重要的问题:“架构”运行得非常好且稳定,但值得做吗?它会产生过多的开销吗?它甚至有意义吗?您个人如何实现并发操作?

最好的亨利克

PS 随意编辑我的问题,提出问题(作为评论),给我起这个想法的名字。

我真的很难解释它,主要是因为我不是以英语为母语的人。不要误会我的意思。我写这篇文章不是为了炫耀。我想做的就是学习(也许写一个更高级的iphone/objective c问题)

0 投票
6 回答
47736 浏览

iphone - 将 NSOperation 子类化为并发和可取消

我找不到关于如何将子类化为NSOperation并发以及支持取消的好的文档。我阅读了 Apple 文档,但找不到“官方”示例。

这是我的源代码:

在我找到的示例中,我不明白为什么使用 performSelectorOnMainThread:。它会阻止我的操作同时运行。

此外,当我注释掉该行时,我的操作会同时运行。但是,isCancelled即使我调用了cancelAllOperations.

0 投票
5 回答
14534 浏览

iphone - 在 iOS4 设备上在后台发送大量数据的最佳实践?

我有一个需要将数据(使用 POST)发送到服务器的应用程序。此功能必须在 NavigationController 子控制器之一上,并且用户应该能够离开此控制器和/或关闭应用程序(仅支持 iPhone4/iOS4)。我应该使用线程/NSOperations 或/和使用现有的异步方法发送数据吗?任何想法/最佳实践如何实现这一点?

0 投票
3 回答
1194 浏览

iphone - NSOperation同步问题

我正在努力寻找一种在 iPhone 应用程序上同步操作的方法。我有三个主要的 NSOperation。

可以看到这三个操作是按顺序正确启动的。但是,正如您可以想象的那样,第一个操作创建一个 UIView 并将其附加到顶部,而最后一个操作应该删除它。

碰巧的是,从图形上讲,操作会立即在屏幕上发生。所以我可以看到表格已经加载,而微调器在屏幕上,或者其他奇怪的不同步的东西。

我知道图形方面的变化发生在主线程上。所以我问我如何修改代码来做它应该做的事情。即:创建微调器、加载数据和删除微调器?有没有一种通用的方法来分离图形操作和数据操作?例如创建两个不同的操作。

谢谢

0 投票
1 回答
2253 浏览

multithreading - 当我在 NSOperation 子类中修改核心数据关系时,为什么我的应用程序会崩溃?

背景

我有以下对象树:

  • 用户可以将组分配给项目。所有后代都设置为该项目。

  • 这会锁定主线程,所以我正在使用 NSOperations。

  • 我正在使用 Apple 批准的方式来执行此操作,观察NSManagedObjectContextDidSaveNotification并合并到主要上下文中。

问题

我的保存失败并出现以下错误:

Failed to process pending changes before save. The context is still dirty after 100 attempts. Typically this recursive dirtying is caused by a bad validation method, -willSave, or notification handler.

我试过的

我已经剥离了我的应用程序的所有复杂性,并制作了我能想到的最简单的项目。并且错误仍然发生。我试过了:

  • 将队列上的最大操作数设置为 1 或 10。

  • refreshObject:mergeChanges:在 NSOperation 子类中的几个点调用。

  • 在托管对象上下文上设置合并策略。

  • 构建和分析。它是空的。

我的问题

如何在 NSOperation 中设置关系而不让我的应用崩溃?当然这不能是Core Data的限制吗?它可以?

编码

下载我的项目:http ://synapticmishap.co.uk/CDMTTest1.zip

主控制器

进行关系操作

数据模型

数据模型

更新 1

我已经进行了更多实验,即使没有合并,仍然会抛出异常。只需在修改关系后将托管对象上下文保存在另一个线程中就足够了。

我有一个与应用程序委托共享的持久存储协调器。我尝试为与我的数据存储具有相同 URL 的线程创建一个单独的 NSPersistentStoreCoordinator,但 Core Data 抱怨。

I'd love to suggestions on how I can make a coordinator for the thread. The core data docs allude to there being a way of doing it, but I can't see how.

0 投票
1 回答
2159 浏览

iphone - 为什么我的 NSOperationQueue 在 iOS 4.0 中的行为不正确?

我之前在 iPhone OS 3.0 中的 iPhone 应用程序中使用过 NSOperationQueue,但现在在 iOS 4.0 中代码无法正常工作。它只在所有后续调用中正常运行一次,它不起作用。iOS 4.0 中的 NSOperationQueue 有变化吗?

相关代码如下: