首先,很抱歉我无法为这个问题想出更好的标题。
这是一个我无法重复但在用户身上发生过多次的崩溃。我正在使用 HockeyApp( QuincyKit ) 来收集崩溃报告。所以无法调试这个问题,只能读取调用栈。但是我读完之后不知道出了什么问题。中间省略了几个不相关的函数调用。
对于 UI 部分,我使用 NSFetchedResultsController 来填充 UITableView。
对于核心数据部分,我使用的是 iOS 5 新引入的父子 MOC:父 MOC 用于主队列,子 MOC 用于资源获取队列。我在处理其中获取的数据后保存子 MOC。一旦我保存了子 MOC,更改应该由 Core Data 自动推送到父 MOC,并且 FRC 应该通过其委托(delegate)查看更改和更新 TableView 。然后,我回调主线程以进行额外的 UI 更新。
具体来说,我可以理解 [UITableView indexPathForRowAtPoint:] 如何调用 [NSFetchedResultsController objectAtIndexPath:],但我不明白为什么它最终调用了我实体的 initWithEntity:insertIntoManagedObjectContext: 以及为什么 initWithEntity:insertIntoManagedObjectContext: 会导致未完成的错误。我认为 [NSFetchedResultsController objectAtIndexPath:] 应该执行 fetch,但它确实在此处执行了 insert。
Exception Type: SIGABRT
Exception Codes: #0 at 0x35e7e32c
Crashed Thread: 0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xe62bdc0 <x-coredata://327F5799-CAB1-4086-8E75-0E87F0E19BF0/Status/p385>''
Last Exception Backtrace:
0 CoreFoundation 0x355c888f __exceptionPreprocess + 162
1 libobjc.A.dylib 0x3796f259 objc_exception_throw + 32
2 CoreData 0x35f124f3 _PFFaultHandlerLookupRow + 1098
3 CoreData 0x35f11d5b _PF_FulfillDeferredFault + 194
4 CoreData 0x35f11c0b _sharedIMPL_pvfk_core + 38
5 XXX 0x0008a5c3 -[Tweet initWithEntity:insertIntoManagedObjectContext:] (Tweet.m:125)
6 XXX 0x0003fd1b -[Status initWithEntity:insertIntoManagedObjectContext:] (Status.m:333)
7 CoreData 0x35f0eded -[NSManagedObject(_NSInternalMethods) _initWithEntity:withID:withHandler:withContext:] + 164
8 CoreData 0x35f0de07 -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] + 134
9 CoreData 0x35f6b6eb _PFRetainedObjectIDCore + 330
10 CoreData 0x35f67065 -[NSManagedObjectContext objectWithID:] + 88
11 CoreData 0x35f32c09 _faultBatchAtIndex + 1352
12 CoreData 0x35f31e73 -[_PFBatchFaultingArray objectAtIndex:] + 42
13 CoreData 0x35f30a87 -[_PFMutableProxyArray objectAtIndex:] + 82
14 CoreData 0x35fdd81d -[NSFetchedResultsController objectAtIndexPath:] + 204
16 XXX 0x0009ebab -[TweetsViewController tableView:heightForRowAtIndexPath:] (TweetsViewController.m:581)
17 UIKit 0x3304dab5 -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 2548
18 UIKit 0x33067c3b -[UITableViewRowData rectForSection:] + 302
19 UIKit 0x33125981 -[UITableViewRowData indexPathsForRowsInRect:] + 136
20 UIKit 0x331258f1 -[UITableView indexPathsForRowsInRect:] + 52
21 UIKit 0x33125889 -[UITableView indexPathForRowAtPoint:] + 28
22 XXX 0x0009c193 -[TweetsViewController updateUI] (TweetsViewController.m:211)
25 XXX 0x00111a6f __block_global_1 (ResourceFetcher.m:68)
26 libdispatch.dylib 0x34458b87 _dispatch_barrier_sync_f_slow_invoke + 82
27 libdispatch.dylib 0x34457ee7 _dispatch_main_queue_callback_4CF$VARIANT$mp + 194
28 CoreFoundation 0x3559b2ad __CFRunLoopRun + 1268
29 CoreFoundation 0x3551e4a5 CFRunLoopRunSpecific + 300
30 CoreFoundation 0x3551e36d CFRunLoopRunInMode + 104
31 GraphicsServices 0x371ba439 GSEventRunModal + 136
32 UIKit 0x3302acd5 UIApplicationMain + 1080
33 XXX 0x000044ff main (main.m:16)
34 XXX 0x00003c50 start + 40
遇到此崩溃问题的用户通常会在崩溃前立即看到表格 View 从充满单元格的状态突然变为空白。我认为这是一个重要的提示,但我想不出所有数据突然消失的任何原因 — 我没有移动或删除数据库文件的代码。
最佳答案
首先,在查找错误时,没有不相关的函数调用,因此您可能应该编辑整个调用堆栈...
看起来您正在请求一个对象(请参阅 objectWithID 调用),但是当托管对象上下文去获取它时,它找不到它。
当您有一个正在删除对象的单独线程,并且您没有正确管理更改时,通常会发生这种情况。
那么,您是否有任何其他线程正在更改核心数据存储的状态?如果是这样,那可能是你的罪魁祸首。
Core Data 并没有那么难......但是它确实有几条规则,如果你不遵守这些规则,你就会有麻烦。
首先,确保您没有从多个线程访问 MOC。
其次,如果多个线程正在更改底层存储,请确保您与所有 MOCS 正确同步 - 使用父/子上下文或查看 DidSave 通知。
编辑
你评论了:
Yes, I'm also suspecting there are some deleting-something-in-use problems. But first of all, do you know why initWithEntity:insertIntoManagedObjectContext: is called here?
是的...它需要实例化对象。查看您的调用堆栈,您可以看到...
您的 UI 正在尝试在主线程上更新...
22 XXX 0x0009c193 -[TweetsViewController updateUI] (TweetsViewController.m:211)
因此,UIKit 会做它的事情,并向您的 Controller 发出委托(delegate)回调...
16 XXX 0x0009ebab -[TweetsViewController tableView:heightForRowAtIndexPath:] (TweetsViewController.m:581)
这会导致您正在谈论的 FRC 调用...
14 CoreData 0x35fdd81d -[NSFetchedResultsController objectAtIndexPath:] + 204
然后,需要对象,所以它被获取...
10 CoreData 0x35f67065 -[NSManagedObjectContext objectWithID:] + 88
好吧,即使是 Core Data 也必须实例化对象。它没有一些神奇的界面。它调用普通的 API 来创建一个托管对象……显然你正在请求一个类型为“Status”的对象
6 XXX 0x0003fd1b -[Status initWithEntity:insertIntoManagedObjectContext:] (Status.m:333)
反过来,这个对象需要一个“Tweet”类型的对象......
5 XXX 0x0008a5c3 -[Tweet initWithEntity:insertIntoManagedObjectContext:] (Tweet.m:125)
然后,当它必须实例化该对象时...由于找不到它而失败。因此,我再次打赌您的同步过程中存在逻辑错误。要么你正在删除一个对象并且没有正确地通知其他上下文,所以他们仍然引用一个已删除的对象......其他语境。
无论哪种方式,我认为这是一个很好的赌注:如果您跟踪更改数据库的方式,那么您就违反了一些在多线程中进行更新的标准协议(protocol)。
事实上,您甚至可以看到您是如何到达那里的...
updateUI 正在从 GCD 调度队列中调用。很可能,在 ResourceFetcher 中,您正在调用主线程。在该代码中,请确保在要求主线程自行更新之前已正确保存上下文并发出所有通知。
您最好监听来自其他 MOC 的 DidSave 事件,然后在从该上下文更新后,调用您的 UI 进行 self 更新。
关于ios - 此 Core Data 崩溃的可能原因是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10866204/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串