- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如果我有一个 Message
对象数组,每个对象都有一个包含数据的 PFile
,是否可以通过像这样异步排队来下载每条消息的数据所以:
for (int i = 0; i < _downloadedMessages.count; i++) {
PFObject *tempMessage = (PFObject *)[_downloadedMessages objectAtIndex:i];
[[tempMessage objectForKey:@"audio"] getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
[self persistNewMessageWithData:data];
}];
}
这似乎导致我的应用程序挂起,即使这应该在后台完成...
使用下面的解决方案:
NSMutableArray* Objects = ...
[self forEachPFFileInArray:Objects retrieveDataWithCompletion:^BOOL(NSData* data, NSError*error){
if (data) {
PFObject *tempObj = (PFObject *)Object[someIndex...];
[self persistNewMessageWithData:data andOtherInformationFromObject:tempObj];
return YES;
}
else {
NSLog(@"Error: %@", error);
return NO; // stop iteration, optionally continue anyway
}
} completion:^(id result){
NSLog(@"Loop finished with result: %@", result);
}];
最佳答案
您可能遇到的是,对于同时运行的大量异步请求,系统可能会由于内存压力和网络停顿或其他资源访问耗尽而阻塞(包括中央处理器)。
您可以使用带有“分配”工具的 Instruments 来验证内存压力的发生。
在内部(即在 Parse 库和系统中)可能有一个变量集,它设置可以同时运行的最大网络请求数。尽管如此,在您的 for
循环中,您将所有请求排入队列。
根据您的情况排队请求意味着什么,此过程根本不是免费的。它可能会消耗大量内存。在最坏的情况下,网络请求将被系统排队,但底层网络堆栈仅执行最大数量的并发请求。其他入队但待定请求卡在那里等待执行,而它们的网络超时已经在运行。这可能会导致取消未决事件,因为它们的超时已过。
好吧,解决上述问题的最明显方法是简单地序列化所有任务。也就是说,它仅在前一个异步任务完成后才启动下一个异步任务(包括完成处理程序中的代码)。可以使用我命名为“异步循环”的异步模式来完成此操作:
“异步循环”是异步的,因此有一个完成处理程序,它会在所有迭代完成时被调用。
typedef void (^loop_completion_handler_t)(id result);
typedef BOOL (^task_completion_t)(PFObject* object, NSData* data, NSError* error);
- (void) forEachObjectInArray:(NSMutableArray*) array
retrieveDataWithCompletion:(task_completion_t)taskCompletionHandler
completion:(loop_completion_handler_t)completionHandler
{
// first, check termination condition:
if ([array count] == 0) {
if (completionHandler) {
completionHandler(@"Finished");
}
return;
}
// handle current item:
PFObject* object = array[0];
[array removeObjectAtIndex:0];
PFFile* file = [object objectForKey:@"audio"];
if (file==nil) {
if (taskCompletionHandler) {
NSDictionary* userInfo = @{NSLocalizedFailureReasonErrorKey: @"file object is nil"}
NSError* error = [[NSError alloc] initWithDomain:@"RetrieveObject"
code:-1
userInfo:userInfo];
if (taskCompletionHandler(object, nil, error)) {
// dispatch asynchronously, thus invoking itself is not a recursion
dispatch_async(dispatch_get_global(0,0), ^{
[self forEachObjectInArray:array
retrieveDataWithCompletion:taskCompletionHandler
completionHandler:completionHandler];
});
}
else {
if (completionHandler) {
completionHandler(@"Interuppted");
}
}
}
}
else {
[file getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
BOOL doContinue = YES;
if (taskCompletionHandler) {
doContinue = taskCompletionHandler(object, data, error);
}
if (doContinue) {
// invoke itself (note this is not a recursion")
[self forEachObjectInArray:array
retrieveDataWithCompletion:taskCompletionHandler
completionHandler:completionHandler];
}
else {
if (completionHandler) {
completionHandler(@"Interuppted");
}
}
}];
}
}
// Create a mutable array
NSMutableArray* objects = [_downloadedMessages mutableCopy];
[self forEachObjectInArray:objects
retrieveDataWithCompletion:^BOOL(PFObject* object, NSData* data, NSError* error){
if (error == nil) {
[self persistNewMessageWithData:data andOtherInformationFromObject:object];
return YES;
}
else {
NSLog(@"Error %@\nfor PFObject %@ with data: %@", error, object, data);
return NO; // stop iteration, optionally continue anyway
}
} completion:^(id result){
NSLog(@"Loop finished with result: %@", result);
}];
关于ios - 一次异步地从多个 pffile 下载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22265390/
我得到了“从 PFFile 到 PFFile 的条件转换总是成功”的提示,它突出显示了 if let tempProductPicture = self.askProductImageArray[0]
从 Parse 检索图像并将其显示在 tableView 上,如果我向下滚动 tableView,应用程序崩溃并给出“ fatal error :数组索引超出范围” 行数由“messagesArray
我想从磁盘获取 PFFile。我在这里了解到 Parse 会在下载所有 PFFile 时对其进行缓存。我现在想知道如何检索该缓存。什么是正确的路径。我使用的路径建议here NSString *pat
我正在尝试根据附加到我从中提取 imageFile 的同一对象的 objectID 检索 PFFile 图像。所有其他细节都被正确拉取(字符串),但是,当我拉取 PFFile 时,会加载该类中的随机图
解析仪表板版本 1.1.2 解析服务器版本2.7.1 环境设置 在 Ubuntu 16.4( digital ocean Droplet)上运行的 Parse-Dashboard 重现步骤 添加新的文
是否可以在运行 Parse Server 的 mlab.com/heroku 中的一个字段名下保存一组图像。我试图在一个字段名称中保存 150 张图像。我知道如何保存一张图片。但是是否有可能在一个字段
我在使用我的 iOS 应用程序从我的数据库中上传的 PFFile 的 URL 流式传输视频时遇到问题。我使用了 Heroku 和 AWS,但我仍然遇到同样的问题。当文件托管在旧的解析服务器中时,它过去
Parse.com 刚刚更新了他们的 SDK 以支持本地存储。但是在安装新的 SDK 之后,PFFile 出现了一些问题。我已经使用相同的方法很长时间了,但是现在我使用的是新的 SDK,我无法让它工作
我正在使用 Parse,并且有一个名为“GolfScorecard”的类,该类有多个键,其中包括一个“scorecardImage”键,它是一个 PFFile。我正在尝试将所有高尔夫记分卡信息显示在
我有一个 UItextView,我可以在其中放置图像并输入文本,一旦完成 TextView,我就会将该 textView 的内容上传到 Parse。 如果我只向 textView 添加 1 个图像,它
我在我的 iOS 应用程序中使用核心数据实现了一个本地数据库,该数据库从由 Parse 驱动的后端填充。 我想要一个 Core Data 实体,它的属性是 PFFile(一个解析文件对象)。 Core
这是我加载图片的方式: func LoadImage(sender:FeedVC, cellId:Int){ self.currentlyLoading = true let quer
我上传了一个 PFFile 到 Parse.com,并保存了 PFFile 的 url。然后我删除了 PFFile,并尝试使用保存的 url 下载 PFFile。成功了! 所以我的问题是:Parse.
在我的聊天应用程序中,我对用户表使用 Parse,获取 ID、图像等。我最近添加了此功能,但遇到了一个问题。当我发送消息时,我创建了一个 NSDictionary,其中包含有关消息的信息,例如时间、消
我已经在这个问题上停留了很长一段时间,我阅读了很多线程,但没有一个描述了我的问题我尝试了一大堆不同的方法来解决这个问题,但没有一个奏效。我有一个从数组中提取并通过 segue 发送到下载详细信息 Vi
我正在尝试使用解析从指针获取图像。我正在尝试从类中提取图像而不发出第二个请求。 这是代码: PFFile * connectImageFile = [object objectForKey:@"pra
我想在一个 PFFile 中保存 2 个数据:一个图像和一个数据声音。这对于图像 (fileData) 来说是正确的,但我想在 Parse.com 中为数据声音 (fileData2) 添加一列。我怎
这是我的 NGINX 设置, HTTPS 服务器 server { listen 443 ssl spdy; location /myparseserver/ {
我正在为我的应用程序使用 Parse 和 MongoDB,但我有一个关于 PFFile 的问题。我想在服务器上保存一个空的 PFFile。事实上,用户不必发送图片,但可以通过其他方式发送。 我想设置一
基本上我正在努力解决这个问题:我安装了一个 FacebookAlbumPicker ( https://github.com/OceanLabs/FacebookImagePicker-iOS ) 现
我是一名优秀的程序员,十分优秀!