奇怪的CoreData调试与发布问题

时间:2012-11-28 17:16:33

标签: iphone ios core-data

好的,我有一个名为Entity的{​​{1}}的coreData模型。像这样......

TechnicalQuery

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

我使用相同的名称为TechnicalQuery -------------- NSString *detail NSDate *createdDate NSString *solution NSString *name ... 创建了一个NSManagedObject子类。

它定义了TechnicalQuery详细信息以及@property详细信息。

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

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

当我同步回服务器时出现问题。

在调试中这很好用。我将同步过程抛到后台线程。然后,该线程查找自上次同步以来已更新的任何TQ,然后将它们转换为@dynamic数据。然后它启动另一个队列并排队这些TQ的所有上传。

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

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

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

然而,(最终到达那里)当在发布模式下运行时(即当我在乐器中进行配置时),产生NSDictionary的功能会被炸毁。它告诉我,属性“细节”是零。当我NSDictionary属性时它告诉我它是nil(在发布模式下)但显示文本(在调试模式下)。

NSLog

我知道发生这种情况的确切行,当我在<Warning>: Exception! *** setObjectForKey: object cannot be nil (key: Detail) 设置密钥的对象时。

通常情况下,我会检查我是不是在某个地方设置了属性,但它确实设置为我可以再次浏览到TQ页面,并且详细文本显示正确!?

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

如果有人可以提供任何关于在哪里寻找的建议,那将是非常棒的。

::编辑1 ::

好的,这很奇怪。

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

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

当我在processArray中的数组中记录数据时,它显示正确。

当我从collectData中的同一个数组中记录相同的数据时,对象仍在数组中,但属性都为空。

由于

::编辑2 ::

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

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

仍然得到相同的结果。

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

再次感谢

::编辑3 ::

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

processArray

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

第2行是来自collectData函数内部的Tech Query的名称和详细信息属性的NSLog。

第4行是processArray函数内部Tech Query的名称和详细属性的NSLog。

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

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

::编辑4 ::

添加带有线程ID的日志。

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!

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

再次感谢。

::编辑5 ::

只是为了向您展示我是如何做到这一点的,以下是来自调试版本的日志......

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!

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

3 个答案:

答案 0 :(得分:3)

虽然我无法准确回答你的问题是什么,但是这个问题出现了,结果发现非主线程并没有保持托管对象上下文保持优化,而它们在某种程度上是在调试中。通过使用当前NSThread的threadDictionary,我们在整个线程生命周期中保持托管对象上下文,并解决了问题。

答案 1 :(得分:1)

我不知道最终答案,但这可能会帮助您更接近解决方案。

我们知道 Debug Release 配置有不同的行为。您应该检查构建设置中的所有差异,并尝试使用不同的那些差异。

我曾在发布上遇到类似的奇怪问题。将优化级别更改为“最快,最小”后,该错误也可以在 Debug 上重现。

答案 2 :(得分:0)

Fogmeister,

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

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

其次,切换到发布模式时代码会发生什么变化?为什么调试编译时标志的更改会改变您的产品。 (由于核心数据在您抛出DEBUG标志时不会发生变化,因此不太可能出现问题。)

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

安德鲁