我正在通过后台线程拥有的新创建的NSManagedObjectContext在后台线程(使用GCD)上执行昂贵的读取操作(约5秒,约30,000个对象)。
但是,我没有在后台执行此操作,因为主线程正在等待持久性存储上的锁定,因此UI被冻结。这是堆栈跟踪:
* thread #1: tid = 0x1c03, 0x3641be78 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore], stop reason = breakpoint 1.1
frame #0: 0x3641be78 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore]
frame #1: 0x36432f06 CoreData`-[_PFManagedObjectReferenceQueue _processReferenceQueue:] + 1754
frame #2: 0x36435fd6 CoreData`_performRunLoopAction + 202
frame #3: 0x35ab9b1a CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 18
frame #4: 0x35ab7d56 CoreFoundation`__CFRunLoopDoObservers + 258
frame #5: 0x35ab80b0 CoreFoundation`__CFRunLoopRun + 760
frame #6: 0x35a3b4a4 CoreFoundation`CFRunLoopRunSpecific + 300
frame #7: 0x35a3b36c CoreFoundation`CFRunLoopRunInMode + 104
frame #8: 0x376d7438 GraphicsServices`GSEventRunModal + 136
frame #9: 0x33547cd4 UIKit`UIApplicationMain + 1080
frame #10: 0x000f337a MyApp`main + 90 at main.m:16
_processReferenceQueue中进行任何需要锁定商店。[MOC updatedObjects]集中只有一个对象。插入或删除的集中没有对象。[MOC save]之后,[MOC updatedObjects]集为空,如预期的那样。_processReferenceQueue中。MOC reset]。同样,重置后的[MOC updatedObjects]集为空,这与预期的一样。此时,在代码中,直到BT完成工作,我才接触MT上的任何托管对象(因此,由于重置使我已经引用的托管对象无效,因此我没有遇到任何问题)。但是,这次MT做了而不是尝试将持久性存储锁定在_processReferenceQueue中。_processReferenceQueue内或外的某个位置请求锁定(用于读取或写入)。但事实并非如此。_processReferenceQueue,而最近重置的MOC不需要。最佳答案
没有更多信息,我所能做的只是猜测。
不幸的是,Core Data没有使用相同的持久性存储协调器为MOC实现读取器/写入器锁定。这意味着对一个线程的读取将阻止其他使用同一持久性存储协调器的线程。
因此,您在后台长时间运行的访存将阻止主线程访存。
您有几种选择。
分解长时间运行的获取,以便按顺序获取小片段。您想进行多次小量获取,而不要在完成当前任务之前再发行下一部分。
这将允许在主线程上进行访存,从而有机会在后台线程上的多个小访存之间进行处理。
另一种选择是创建一个单独的持久性存储协调器,将您的后台MOC连接到该持久性存储协调器,然后运行获取。如果您使用多个持久性存储协调器,那么您可以同时拥有多个阅读器,并且它们不会永久性地相互阻塞。
编辑
I've definitely thought about breaking it up. But this isn't a case where I'm trying to make two simultaneous fetches play nicely together. The MT shouldn't be touching Core Data at this point. – BrianJStafford
UIManagedDocument还是在主线程上创建了MOC,还是使用NSMainQueueConcurrencyType?[_PFManagedObjectReferenceQueue _processReferenceQueue:]的调用方式。_processReferenceQueue:处放置一个断点只是为了确保您可以获取该断点。performBlock与它进行简单的交易,看看是否达到断点。-[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore]
-[_PFManagedObjectReferenceQueue _processReferenceQueue:]
dispatch_async并获取所有100,000个对象。
关于iphone - 主线程在执行后台线程时正在等待[NSManagedObjectContext(_NSInternalAdditions)lockObjectStore],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12168761/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我是ruby的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption