好的,我有一个名为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)。
有两个函数NSMutableDictionary
和collectData
。 processArray
函数执行获取请求并将结果放入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设备日志复制的。
答案 0 :(得分:3)
虽然我无法准确回答你的问题是什么,但是这个问题出现了,结果发现非主线程并没有保持托管对象上下文保持优化,而它们在某种程度上是在调试中。通过使用当前NSThread的threadDictionary,我们在整个线程生命周期中保持托管对象上下文,并解决了问题。
答案 1 :(得分:1)
我不知道最终答案,但这可能会帮助您更接近解决方案。
我们知道 Debug 和 Release 配置有不同的行为。您应该检查构建设置中的所有差异,并尝试使用不同的那些差异。
我曾在发布上遇到类似的奇怪问题。将优化级别更改为“最快,最小”后,该错误也可以在 Debug 上重现。
答案 2 :(得分:0)
Fogmeister,
你还没有给我们太多的信息。因此,任何人都会猜测。
首先,您可以调试代码的发行版本。只需更改Xcode方案中的配置文件即可。
其次,切换到发布模式时代码会发生什么变化?为什么调试编译时标志的更改会改变您的产品。 (由于核心数据在您抛出DEBUG标志时不会发生变化,因此不太可能出现问题。)
为了进一步帮助您,SO社区通常需要查看一些代码。如果你分享一些,人们可能会看着它来帮助你。
安德鲁