- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以,在前一段时间了解完成 block 之后,我非常喜欢使用完成 block 。我喜欢关闭,我喜欢将任何东西传递到任何我想要的地方的能力。
作为线程编程的新手,我一直远离 GCD 和 NSOperation——但最近我不得不编写异步更新到核心数据的东西,我开始怀疑我的“所有完成 block ”始终”的方法。
所以这里有一个我正在质疑自己的例子:我有一系列可能相当大的数据(图像、声音、视频,你有什么)要上传到某处的服务器。这些数据的元数据存储在 Core Data 中,我有一个时间戳,用于决定应上传哪些对象。所有这些上传都应该按顺序完成。
我编写的代码基本上只是一个带有完成 block 的函数,在 block 的末尾有一个对自身的调用,如下所示:
(void)uploadAllAsynchronously {
... // First figure out what to upload based on core data
// Here comes the completion block in question
void(^blk)(BOOL) = ^(BOOL)uploadSuccess {
... // if upload successful, update core data to mark what has been uploaded
[self uploadAllAsynchronously]; // Recursively calls the function that contains this block. I actually have a weak self, or if that fails to break a retain cycle, I should be able to pass in a NSManagedObjectContext as an argument.
}
[NSURLConnection sendAsynchronousRequest:... queue:... completionHandler:blk];
}
这应该行得通,对吧?这里有什么完全危险的东西建议我必须使用 GCD 并处理我自己的队列吗?我问这个是因为我现在遇到了一些麻烦,可能其中的数据会出现不同的线程由于异步调用而无法正确更新,但不确定我的代码的哪一部分是罪魁祸首。
提前致谢。
最佳答案
您的 block 类型错误。
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse *, NSData *, NSError *))handler
显示,完成黑色的类型是
void (^) (NSURLResponse *, NSData *, NSError *)
不是
void (^) (BOOL)
你应该把 blk
改成类似
void (^blk) (NSURLResponse *, NSData *, NSError *) = ^ (NSURLResponse *response, NSData *data, NSError *error) {
//...
};
这样写会更有格调
[NSURLConnection sendAsynchronousRequest:theRequest queue:theQueue completionHandler:^ (NSURLResponse *response, NSData *data, NSError *error) {
//...
}];
完成 block 与方法内联。
关于在完成处理程序中对 NSManagedObjectContext
执行操作的问题:只要将 NSOperationQueue
传递给 sendAsynchronousRequest:queue:completionHandler 就可以了:
与创建托管对象上下文的代码相同。但是作为the documentation for NSManagedObjectContext
州
Core Data uses thread (or serialized queue) confinement to protect managed objects and managed object contexts (see “Concurrency with Core Data”). A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method. You should not, therefore, initialize a context on one thread then pass it to a different thread. Instead, you should pass a reference to a persistent store coordinator and have the receiving thread/queue create a new context derived from that.
如果您传递的队列不是您创建托管对象上下文的队列,您必须执行以下操作之一
在创建托管对象上下文的队列上调用 -[NSOperationQueue addOperation:]
。
在进行核心数据操作的队列上创建第二个托管对象上下文(具有相同的持久存储协调器)。
在进行核心数据操作的队列上创建第二个托管对象上下文和第二个持久存储协调器。
使用锁定。
关于 Concurrency with Core Data 的文档明确表示您必须使用线程限制(上面的选项 1-3)或使用锁定(上面的选项 4)。
这是文档中关于使用锁的说法:
If you choose not to use the thread containment pattern—that is, if you try to pass managed objects or contexts between threads, and so on—you must be extremely careful about locking, and as a consequence you are likely to negate any benefit you may otherwise derive from multi-threading.
这就是文档所说的不仅有每线程管理的对象上下文,还有每线程持久存储协调器:
This approach provides for greater concurrency at the expense of greater complexity (particularly if you need to communicate changes between different contexts) and increased memory usage.
关于ios - 关于使用完成 block 排队,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14084455/
我有一些基于 TThreads 的操作。现在我需要创建包含要完成的作业列表的线程,然后在前一个完成后立即触发每个线程...我应该如何编写它?我不能允许线程同时运行,因为可能有超过 10 000 个操作
我正在尝试使用 RxJS 来实现服务调用限制/排队。 例如,Google Maps 的 Geocoder API。假设我不希望它每秒被调用一次以上,但是我的应用程序的一个或多个部分可能会比这更频繁
我目前正在通过 freecodecamp 网站的 javascript 部分进行练习,我试图理解为什么特定的方法可以解决它。 function nextInLine(arr, item) { /
详情 我有一个带有动画的功能,当点击按钮时它会.append一个div到body。然后,div 将为其位置向下移动一点点设置动画。添加另一个时,所有 div 也会向下移动,因此它们不会重叠。 现在我们
我有一个正在发送 http 请求的应用程序,每次用户键入时都会返回一个 promise 。我让它每 500 毫秒去抖一次。有时我请求的 api 需要很长时间才能响应。例如,我对 a 发出搜索请求,该请
我一直在做一项作业,涉及实现包含空指针的队列,以便它们可以针对任何类型的数据进行泛化。我目前遇到一个奇怪的问题,虽然出队节点减少了列表的大小但没有返回我期望的节点。在出列操作中省略对 free() 的
我正在寻找概述“排队”的文章和引用资料(我在这里可能甚至没有使用正确的术语)。我希望通过 Redis、RabbitMQ、Celery、Kombu 以及我尚未了解的任何其他组件以及它们如何组合在一起的世
我使用 mbostock/queue用于排队一些异步操作。更多的是速率限制(UI 生成的事件很少,后端可以慢慢处理),并确保它们按顺序处理。我像这样使用它 function request(d, cb
我有我的 android 应用程序,它不是为离线工作而构建的,因此它依赖于网络连接/数据。 应用程序进行大量网络调用,使用新数据集更新 api。 我正在对其进行更改以使其脱机工作。 方法我想我将创建一
我想将 div 的内容更改 3 次,每次更改之间延迟 1 秒。delay() 在此代码中不起作用: $('#import-status-msg').html('Importing content ..
我需要根据存储在数据库中的时间线在 jQuery 中制作一系列动画。我将这些信息与函数名称(动画、幻灯片、淡入淡出...)、函数的选项/参数以及函数的回调一起存储。 我知道 jQuery 确实有 .q
我有以下方法 public async Task SomeMethod(parameters) { // here we execute some instructions which are
在我的 winforms 应用程序中,我有一个包含对象的队列: Queue _queuedRows = new Queue(); 对于每个对象,我必须启动一个单独的 backgroundwor
我有以下代码: for (int i = 1; i <= 500; i++) { BackgroundWorker t = new BackgroundWorker(); t.DoWo
我有一个 CAShapeLayer,我在其中设置了一个圆圈的动画。动画是先顺时针“撤消”圆圈,然后顺时针重画圆圈。有点像“旋转圈”。另一种说法是:将路径描边终点移动到起点,然后将起点移到终点。 动画本
所以,在前一段时间了解完成 block 之后,我非常喜欢使用完成 block 。我喜欢关闭,我喜欢将任何东西传递到任何我想要的地方的能力。 作为线程编程的新手,我一直远离 GCD 和 NSOperat
我有一些使用 FMDB sqllite 包装器 ( https://github.com/ccgus/fmdb ) 的代码,并且我希望从多个线程执行此代码。因此,我使用 FMDatabaseQueue
页面加载速度比预期慢。我用 Firebug 检查了时间线,我看到很多图像阻塞: http://i.imgur.com/tenTNVH.png 我想我做错了什么。 (我知道我这里有双 jquery,会消
我在使用 Alamofire 时遇到任务执行问题我使用了两次 Alamofire,第一次是收集数据( token ),然后我将使用它来发送我的 Post 请求。 我的两次请求之间的问题,数据的恢复是在
我想知道如何将选定的 YouTube 视频添加到临时播放列表/播放队列中? 我有一个选项,用户必须选择要包含在播放队列中的所有视频。 Click on the ADD icon (black back
我是一名优秀的程序员,十分优秀!