4

好的,我有一个Entity名为coreData 的模型TechnicalQuery。像这样...

TechnicalQuery
--------------
NSString *detail
NSDate *createdDate
NSString *solution
NSString *name
...

在应用程序中是一个同步过程(应用程序按规范离线),使用该应用程序的人将在他们回到办公室并连接时进行同步。无论如何,这并不重要。

我创建了一个使用相同名称的NSManagedObject子类。TechnicalQuery

它具有@property定义的细节和@dynamic细节。

目前,数据库中只有一个技术查询。我可以通过使用该应用程序查看包含所有详细信息的技术查询“屏幕”等来查看这一点……它显示了名称、解决方案、详细信息、创建日期等……一切都在那里。

我可以在应用程序中更新解决方案文本。然后当我稍后回去时,更新仍然存在。核心数据工作正常。

当我同步备份到服务器时,我的问题就出现了。

在调试中这工作正常。我将同步过程丢给了后台线程。然后,该线程查找自上次同步以来已更新的任何 TQ,然后将它们转换为JSON数据。然后它启动另一个队列并将这些 TQ 的所有上传排队。

笔记!我绝不会ManagedObjects在线程之间传递。我在一个函数中运行 fetchrequest,然后存储数组并在下一个函数(同一线程)中处理数组。唯一传递给下一个线程的是JSON它需要发送到的数据和对象特定的 URL,根本没有 CoreData 对象。

JSON数据由子类文件中的一个函数收集ManagedObject(它实际上属于一个类别,NSManagedObject但你明白了......)该函数首先将对象转换为NSDictionary与服务器所需格式匹配的对象,然后再进行转换。

无论如何,在调试模式下(即直接从 Xcode 运行到我的 iPhone 5 它工作正常。字典(和上传数据都填充得很好)。

然而,(终于到了那里)在发布模式下运行时(即当我在仪器中分析时)产生 NSDictionary 炸弹的功能。它告诉我属性“详细信息”为零。当我NSLog的属性告诉我它是 nil(在发布模式下)但显示文本(在调试模式下)。

<Warning>: Exception! *** setObjectForKey: object cannot be nil (key: Detail)

我知道发生这种情况的确切线路,并且是在我为NSMutableDictionary.

通常我会检查我没有在某处设置属性,但它肯定是设置的,因为我可以再次浏览到 TQ 页面并且详细文本显示正确!?

我真的不知道现在该去哪里。

如果有人可以就在哪里看等提供任何建议,那就太棒了。

::编辑 1::

好吧,这很奇怪。

我在收集和处理数据的对象中有一个强大的属性数组(称为recordArray)。

有两个功能collectDataprocessArray。该collectData函数执行获取请求并将结果放入recordArray。然后该processArray函数迭代数组并处理每个项目。

当我将数据记录在数组中时,collectData它会正确显示所有内容。

当我从对象中的同一数组中记录相同的数据时,数组中processArray仍然存在,但属性全部为空。

谢谢

::编辑 2::

我尝试摆脱属性数组并将其替换为输入/输出模式。

即从 collectData 函数输出数组,然后将其输入到 processArray 函数。

仍然得到相同的结果。

真的用这个把我的头发拉出来。

再次感谢

::编辑 3::

只需从 NSLog 条目中添加一些控制台日志。

1. Nov 29 09:56:39 Olivers-iPhone5 [2705] <Warning>: Collecting technical queries
2. Nov 29 09:56:39 Olivers-iPhone5 [2705] <Warning>: Tech Query: Name: test Detail: Test description from Olivers iPhone.
3. Nov 29 09:56:39 Olivers-iPhone5 [2705] <Warning>: pushing tech queries
4. Nov 29 09:56:39 Olivers-iPhone5 [2705] <Warning>: Tech Query: Name: (null) Detail: (null)
5. Nov 29 09:56:39 Olivers-iPhone5 [2705] <Warning>: (null)
6. Nov 29 09:56:39 Olivers-iPhone5 [2705] <Warning>: Exception! *** setObjectForKey: object cannot be nil (key: Detail)
7. Nov 29 09:56:39 Olivers-iPhone5 [2705] <Warning>: Something Went Wrong!

您可以看到这些都在不到一秒钟的时间内发生。

第 2 行是来自 collectData 函数内部的技术查询的名称和详细信息属性的 NSLog。

第 4 行是来自 processArray 函数内部的技术查询的名称和详细信息属性的 NSLog。

如您所见,第 4 行显示属性的空值。

第 6 行是尝试将详细信息属性添加到 NSMutableArray 的异常日志。它出错了,因为 detail 属性为空。

::编辑 4::

添加带有线程 ID 的日志。

1. Nov 29 10:32:08 Olivers-iPhone5 [2749] <Warning>: Collecting technical queries. Thread: <NSThread: 0x1d263fa0>{name = (null), num = 8}
2. Nov 29 10:32:08 Olivers-iPhone5 [2749] <Warning>: Tech Query: Name: test Detail: Test description from Olivers iPhone. Thread: <NSThread: 0x1d263fa0>{name = (null), num = 8}
3. Nov 29 10:32:08 Olivers-iPhone5 [2749] <Warning>: pushing tech queries. Thread: <NSThread: 0x1d263fa0>{name = (null), num = 8}
4. Nov 29 10:32:08 Olivers-iPhone5 [2749] <Warning>: Tech Query: Name: (null) Detail: (null) Thread: <NSThread: 0x1d263fa0>{name = (null), num = 8}
5. Nov 29 10:32:08 Olivers-iPhone5 [2749] <Warning>: (null)
6. Nov 29 10:32:08 Olivers-iPhone5 [2749] <Warning>: Exception! *** setObjectForKey: object cannot be nil (key: Detail)
7. Nov 29 10:32:08 Olivers-iPhone5 [2749] <Warning>: Something Went Wrong!

你可以从这里看到我绝对没有在线程之间传递任何东西。这一切都发生在同一个线程上。

再次感谢。

::编辑 5::

只是为了向您展示我是如何编造的,这里是来自调试版本的日志......

1. 2012-11-29 10:36:08.471 [2767:161f] Collecting technical queries. Thread: <NSThread: 0x1cd52fb0>{name = (null), num = 8}
2. 2012-11-29 10:36:08.474 [2767:161f] Tech Query: Name: test Detail: Test description from Olivers iPhone. Thread: <NSThread: 0x1cd52fb0>{name = (null), num = 8}
3. 2012-11-29 10:36:08.474 [2767:161f] pushing tech queries. Thread: <NSThread: 0x1cd52fb0>{name = (null), num = 8}
4. 2012-11-29 10:36:08.475 [2767:161f] Tech Query: Name: test Detail: Test description from Olivers iPhone. Thread: <NSThread: 0x1cd52fb0>{name = (null), num = 8}
5. 2012-11-29 10:36:08.476 [2767:161f] Test description from Olivers iPhone.
6. 2012-11-29 10:36:08.483 [2767:1623] Uploading to url <I can't put the URL here as it's private>
7. 2012-11-29 10:36:08.906 [2767:520f] Upload Done

这是完全相同的代码。唯一的区别是它在调试模式下运行,并且日志是从 Xcode 而不是 Organizer 设备日志中复制的。

4

3 回答 3

3

虽然我不能确切地回答你的问题是什么,但这个问题出现在我身上,结果证明非主线程没有保持托管对象上下文保持优化,而它们以某种方式处于调试状态。通过使用当前 NSThread 的 threadDictionary,我们在整个线程生命周期中保留了托管对象上下文,问题得到了解决。

于 2013-05-29T10:34:39.540 回答
1
于 2012-11-29T21:22:44.197 回答
0

雾化器,

你并没有真正给我们太多信息。因此,任何人都会猜测。

首先,您可以调试代码的发布版本。只需更改 Xcode 方案中的配置文件。

其次,当您切换到发布模式时,您的代码有哪些变化?为什么调试编译时标志的更改会更改您的产品。(因为当你抛出 DEBUG 标志时 Core Data 不会改变,所以这很可能不是问题所在。)

为了进一步帮助您,SO 社区通常需要查看一些代码。如果你分享一些,人们可能会看它来帮助你。

安德鲁

于 2012-11-29T12:36:50.183 回答