- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在创建一个 NSManagedObjectContext
在私有(private)队列中处理我从文件和/或服务中获取的数据更新:
NSManagedObjectContext *privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
privateContext.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator;
performBlock:
之间的区别和
performBlockAndWait:
方法...要执行我的数据更新,我目前正在这样做:
[privateContext performBlock: ^{
// Parse files and/or call services and parse
// their responses
// Save context
[privateContext save:nil];
dispatch_async(dispatch_get_main_queue(), ^{
// Notify update to user
});
}];
[privateContext performBlockAndWait: ^{
// Parse files and/or call services and parse
// their responses
// Save context
[privateContext save:nil];
}];
// Notify update to user
最佳答案
你是对的,你想用 MOC 做的任何事情都必须在 performBlock
内完成。或 performBlockAndWait
.请注意,保留/释放对于托管对象是线程安全的,因此您不必在这些块之一内保留/释放托管对象上的引用计数。
它们都利用同步队列来处理消息,这意味着一次只能执行一个块。嗯,这几乎是真的。见performBlockAndWait
的说明.在任何情况下,对 MOC 的访问都将被串行化,以便一次只有一个线程正在访问 MOC。
tl;dr 不要担心差异,始终使用 performBlock
.
事实差异
有许多不同之处。我相信还有更多,但这里是我认为最重要的理解。
同步与异步performBlock
是异步的,因为它立即返回,并且该块在 future 某个时间在某个未公开的线程上执行。通过 performBlock
提供给 MOC 的所有区块将按照添加的顺序执行。performBlockAndWait
是同步的,因为调用线程将等到块执行完毕后再返回。块是在其他线程中运行,还是在调用线程中运行并不是那么重要,并且是一个无法信任的实现细节。
但是请注意,它可以实现为“嘿,某个其他线程,去运行这个块。我会坐在这里什么都不做,直到你告诉我它完成了。”或者,它可以实现为“嘿,Core Data,给我一个锁,防止所有其他块运行,这样我就可以在我自己的线程上运行这个块。”或者它可以以其他方式实现。再次,实现细节,它可以随时更改。
不过,我会告诉你这一点,我上次测试它时,performBlockAndWait
在调用线程上执行块(意思是上一段中的第二个选项)。这只是帮助您了解正在发生的事情的真正信息,不应以任何方式依赖。
重入性performBlock
是 总是 异步,因此不可重入。好吧,有些人可能会认为它是可重入的,因为您可以从使用 performBlock
调用的块中调用它。 .但是,如果您这样做,所有调用 performBlock
将立即返回,并且该块至少在 之前不会执行当前 执行块完全完成它的工作。
[moc performBlock:^{
doSomething();
[moc performBlock:^{
doSomethingElse();
}];
doSomeMore();
}];
doSomething()
doSomeMore()
doSomethingElse()
performBlockAndWait
是
总是 同步。此外,它也是可重入的。多次调用不会死锁。因此,如果您最终拨打
performBlockAndWait
当你在一个由于另一个
performBlockAndWait
而运行的块中时,然后就OK了。您将获得预期的行为,因为第二次调用(以及任何后续调用)不会导致死锁。此外,正如您所期望的那样,第二个将在返回之前完全执行。
[moc performBlockAndWait:^{
doSomething();
[moc performBlockAndWait:^{
doSomethingElse();
}];
doSomeMore();
}];
doSomething()
doSomethingElse()
doSomeMore()
performBlock
始终遵循内部队列的 FIFO 结构。每个块都会被插入到队列中,并且只有在它被移除时才会运行,按照 FIFO 的顺序。
performBlockAndWait
打破 FIFO 排序,因为它跳过已经入队的块队列。
performBlockAndWait
提交的块不必等待队列中正在运行的其他块。有很多方法可以看到这一点。一个简单的就是这个。
[moc performBlock:^{
doSomething();
[moc performBlock:^{
doSomethingElse();
}];
doSomeMore();
[moc performBlockAndWait:^{
doSomethingAfterDoSomethingElse();
}];
doTheLastThing();
}];
doSomething()
doSomeMore()
doSomethingAfterDoSomethingElse()
doTheLastThing()
doSomethingElse()
performBlockAndWait
是抢占式的,可以跳过FIFO队列。
performBlock
.如果你在块内做了一些愚蠢的事情,那么你可能会死锁,但调用
performBlock
永远不会陷入僵局。您可以从任何地方调用它,它只会将块添加到队列中,并在将来的某个时间执行它。
performBlockAndWait
轻松获得死锁。 ,特别是如果您从外部实体可以调用的方法中调用它,或者在嵌套上下文中不加选择地调用它。具体来说,如果父级调用
performBlockAndWait
,您几乎肯定会死锁您的应用程序。在一个 child 身上。
processPendingChanges
之间的任何事件。 .您可以阅读有关此方法为何重要的详细信息,但“用户事件”中发生的事情对通知、撤消管理、删除传播、更改合并等有影响。
performBlock
封装了一个“用户事件”,这意味着代码块在对
processPendingChanges
的不同调用之间自动执行。 .
performBlockAndWait
不封装“用户事件”。如果您希望将块视为不同的用户事件,则必须自己进行。
performBlock
将块包装在它自己的自动释放池中。
performBlockAdWait
不提供唯一的自动释放池。如果你需要一个,你必须自己提供。
performBlockAndWait
的理由并不多。 .我敢肯定有人有一个无法以任何其他方式完成的用例,但我还没有看到它。如果有人知道该用例,请与我分享。
performBlockAndWait
在父上下文中(永远不要在
NSMainConcurrencyType
MOC 上这样做,因为它可能会锁定您的 UI)。例如,如果要确保在当前块返回并且其他块有机会运行之前数据库已完全保存到磁盘。
performBlockAndWait
,测试之外。
performBlockAndWait
.结果,也许它已经改变了一些,我只是错过了它,因为它不再让我感兴趣……但我对此表示怀疑。
关于ios - performBlock : and performBlockAndWait:? 之间的行为差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32198678/
我想创建一个基于 jQuery 的非常简单的 html 编辑器(不是所见即所得)。 我的问题是如何制作 textarea或 div可能 在上面写一些文字 然后样式即标签(例如 some stuff 将
根据文档 isset 条款“测试此项目中是否已设置给定属性”。我不明白设置属性时 isset 返回 true 还是 false 在下面的代码片段中,当 env.JAVA_HOME 未设置时,java.
我正在尝试取消映射 o这是执行 :only 的默认命令( :help :only ),所以我尝试的第一件事是: nmap o 这种作品,除非我按 ,等待超过timeoutlen ms 然后按 o
我有以下型号: class MetaData(models.Model): created_at = models.DateTimeField(auto_now_add=True, auto_
下面列出了两行代码。两者对日期和时间的期望相同,但只有一个有效。我正在使用 R 3.1。 以下不起作用: DateTime2=strftime("08/13/2010 05:26:24.350", f
我有一个关于 C 代码的问题。 #include void foo(void){ int a; printf("%d\n",a); } void bar(void){
如果文件大小 > 8k,为什么读取的最后一个字节 = 0? private static final int GAP_SIZE = 8 * 1024; public static void main(
我有一个命令 Get-Testdata从不同来源检索测试数据并将这些数据存储到 PSObject以不同的值作为属性。然后将对象总数存储为数组,以便于操作、排序、计算等。 我的问题是我希望能够将这些数据
我正在使用 epoll 将大消息写入使用 HTTP 协议(protocol)的服务器。 fds 都设置为非阻塞,我正在使用边缘触发事件。我知道对于 EPOLLIN,我需要循环读取 fd,直到返回 EA
这对我来说听起来很奇怪: $test_1 = 'string'; $test_2 = '0'; var_dump(intval($test_1)); // Output: int 0 var_dump
这个问题在这里已经有了答案: Java: Integer equals vs. == (7 个回答) 7年前关闭。 请您解释以下行为。 public class EqAndRef { publ
Drupal 的行为到底是什么? 它为模块开发人员提供什么类型的服务层? 它映射到 jQuery.ready 的关系类型是什么? 最佳答案 长版:Drupal.behaviors 不仅仅是 jQuer
以下代码: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ for (int i=0
人们可以将项目添加到数据库中。我让他们选择在此时添加它,或手动选择日期。 因此我得到了这个 HTML 结构。 (请注意,我将日期和时间选择器妥协为只有一行文本) Selec
创建了一个数据框: simpleDF is.na(simpleDF$vals) [1] TRUE TRUE FALSE > is.nan(simpleDF$vals) [1] FALSE TRU
我有一个大的 docker 镜像 A,我创建了一个新的 Dockerfile FROM A RUN rm /big-folder 我尝试使用以下方法构建图像: docker build --squas
我想知道以下情况下 JVM 的行为是什么: JVM 最小堆大小 = 500MB JVM 最大堆大小 = 2GB 操作系统有 1GB 内存 JVM启动后,程序运行一段时间后,使用内存超过1GB。我想知道
我们正在使用 spikeearrest 策略,但我们不了解其工作原理。峰值逮捕配置如下: 5pm 阅读文档,我们了解到,如果我们在一分钟内调用此流超过 5 次,则该策略将在第 5 次之后
我正在使用 cURL 发送 POST 请求: curl http://tarvos.local:8080/partial_Users/2 -d '{currentPage : 1, firstID :
我的表中有 6442670 条记录,我正在使用以下命令获取它们jdbctemplate 使用行号一次 1000000 个。以下是查询 select * from (select rowNum rn
我是一名优秀的程序员,十分优秀!