好的,我有一个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)。
有两个功能collectData
和processArray
。该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 设备日志中复制的。