在 Objective-C 中从异步块增加变量

2024-05-05

我在 Objective-C 中开发的服务遇到了一些难题。该服务的目的是解析核心数据实体列表并为每个对象下载相应的图像文件。该服务的原始设计因太多同时下载请求而阻塞了我的网络服务器。为了解决这个问题,我将负责执行下载请求的代码移至递归方法中。每个下载请求的完成处理程序将再次调用该方法,从而确保每次下载都将等待前一个下载完成后再分派。

事情变得棘手的是负责实际更新我的核心数据模型和进度指示器视图的代码。在下载的完成处理程序中,在方法递归之前,我对负责更新核心数据的块进行异步调用,然后更新视图以显示进度。该块需要有一个变量来跟踪该块已执行的次数。在原始代码中,我可以简单地拥有一个具有块作用域的方法级变量,该变量将在块内递增。由于该方法现在是递归的,因此该策略不再有效。方法级别变量只会在每次递归时重置。由于块调用的异步性质,我不能简单地将变量传递到下一个级别。

我在这里完全不知所措。谁能建议一种处理这个问题的方法?

Update:正如 Matt 下面指出的,这里的核心问题是如何控制请求的时间。经过更多研究后,我发现了为什么我的原始代码不起作用。事实证明,一旦第一个任务启动,超时间隔就开始运行,一旦时间到了,任何其他请求都将失败。如果您确切知道所有请求将花费多少时间,则可以简单地增加请求的超时时间。然而,更好的方法是使用 NSOperationQueue 来控制何时分派请求。有关如何执行此操作的一个很好的示例,请参阅:https://code-examples.net/en/q/19c5248 https://code-examples.net/en/q/19c5248如果您采用这种方法,请记住,您必须调用在 downloadTask 的完成处理程序上创建的每个操作的completeOperation() 方法。

一些示例代码:

-(void) downloadSkuImages:(NSArray *) imagesToDownload onComplete:(void (^)(BOOL update,NSError *error))onComplete
{
    [self runSerializedRequests:imagesToDownload progress:weakProgress downloaded:0 index:0 onComplete:onComplete ];
}

-(void)runSerializedRequests:(NSArray *) skuImages progress:(NSProgress *) progress downloaded:(int) totalDownloaded index:(NSUInteger) index onComplete:(void (^)(BOOL update,NSError *error))onComplete 
{
     int __block downloaded = totalDownloaded;

     TotalDownloadProgressBlock totalDownloadProgressBlock =  ^BOOL (SkuImageID *skuImageId, NSString  *imageFilePath, NSError *error) {
          if(error==nil) {
                  downloaded++;
                  weakProgress.completedUnitCount = downloaded;
                  //save change to core-data here
                  }
          else {
                        downloaded++;
                        weakProgress.completedUnitCount = downloaded;
                        [weakSelf setSyncOperationDetail:[NSString stringWithFormat:@"Problem downloading sku image %@",error.localizedDescription]];
                      }

          if(weakProgress.totalUnitCount==weakProgress.completedUnitCount) {
                              [weakSelf setSyncOperationIndicator:SYNC_INDICATOR_WORKING];
                              [weakSelf setSyncOperationDetail:@"All product images up to date"];
                              [weakSelf setSyncOperationStatus:SYNC_STATUS_SUCCESS];
                              weakProgress.totalUnitCount = 1;
                              weakProgress.completedUnitCount = 1;
                              onComplete(false,nil);
                              return true;
                          }
          return false;
     };

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:nil
    completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {

                NSLog(@"finished download %u of %lu", index +1, (unsigned long)skuImages.count);
                if(error != nil)
                {                    
                    NSLog(@"Download failed for URL: %@ with error: %@",skuImage.url, error.localizedDescription);
                }
                else
                {
                    NSLog(@"Download succeeded for URL: %@", skuImage.url);
                }
                dispatch_async(dispatch_get_main_queue(), ^(void){

                    totalDownloadProgressBlock(skuImageId, imageFilePath, error);

                });

                [self runSerializedRequests:manager skuImages:skuImages progress:progress downloaded:downloaded index:index+1 onComplete:onComplete ];
            }];

            NSLog(@"Starting download %u of %lu", index +1, (unsigned long)skuImages.count);
            [downloadTask resume];
}

该服务的原始设计因太多同时下载请求而阻塞了我的网络服务器。为了解决这个问题,我将负责执行下载请求的代码移至递归方法中。

但这从来都不是解决问题的正确方法。将单个持久自定义 NSURLSession 与您自己的配置一起使用,并设置配置的httpMaximumConnectionsPerHost.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Objective-C 中从异步块增加变量 的相关文章

  • 比较具有相同值但顺序不同的两个数组

    我有 2 个 nsarray 具有相同的值但顺序不同 NSArray array1 0 1 2 3 NSArray array2 2 3 1 0 我需要一种方法来确定两个数组是否具有不同顺序的相同值 Kind of BOOL isSameV
  • iOS UIView子类,将透明文本绘制到背景

    我想将文本绘制到 UIView 上的子类上 以便文本从形状中切出 并且视图后面的背景显示出来 就像在 OSX Mavericks 徽标中找到的那样here http www n3rdabl3 co uk wp content uploads
  • 使用 iOS 7 检索设备 WiFi MAC 地址

    我们的应用程序使用设备 WiFi MAC 地址来唯一标识设备 根据苹果文档 https developer apple com news id 8222013a我们将开始使用 UIDevice 的identifierForVendor 属性
  • 创建自定义 MCBrowserViewController

    有没有办法创建一个UITableView包含在中找到的相同信息MCBrowserViewController 我当前的代码只允许推送与我的应用程序设计不同的标准视图 self browserVC MCBrowserViewControlle
  • 从视频生成缩略图 - ios7

    我用这个作为参考 从视频 URL 或 iPhone SDK 中的数据获取缩略图 https stackoverflow com a 6027285 1145339 该方法使用 MPMoviePlayerController 类而不是 AVF
  • Java:高性能消息传递(单生产者/单消费者)

    我最初问这个问题here https stackoverflow com questions 3367192 java is while true loop in a thread bad whats the alternative 但我意
  • 方向改变时重新定位控件

    我知道自动布局可用于在方向改变时使尺寸和位置保持一致 当方向改变时 是否可以完全改变布局 例如 请查看下面的纵向模式下简单登录屏幕的线框 现在 如果我旋转设备 我想完全重新定位控件 这种事情可以用自动布局来完成吗 如果没有 我该怎么办 谢谢
  • -all_load 其他链接器标志导致第 3 方框架中的重复符号错误

    我有一个用于内部应用程序的静态库 其中包含一些常见的实用程序代码 从以前的 SO 帖子中 我发现为了在运行时加载静态库中的类别 我需要包括 all load ObjC在 构建设置 中的 其他链接器标志 字段中 但是 对于我也在使用的闭源第三
  • 为什么在尝试编译此代码时会收到错误“错误:未知类型名称'虚拟'”?

    Code struct IRenderingEngine virtual void Initialize int width int height 0 virtual void Render const 0 virtual void Upd
  • NSCalendar 返回明年第一周上周一的错误日期

    我使用下面的代码使用随机日期来计算上周一 哪个工作文件但我的代码在明年日期中断 下面是相同的代码 NSDate date NSDate dateWithTimeIntervalSince1970 1483620311 228 NSLog c
  • 从一个模态视图无缝翻转到另一个模态视图,而不显示纯色背景

    我的 iPad 应用程序的 UI 如下 当我点击Settings按钮 我希望对话框水平翻转以显示设置对话框 我这个工作正常 但是 当对话翻转时会显示背景颜色 如你看到的 有什么办法可以让对话框翻转时不显示该颜色块吗 我希望它看起来更加无缝
  • iOS:生成pdf时绘制文本时如何设置字体?

    我在ios应用程序中使用drawpdf函数生成pdf 同时调用nsobject类中的drawtext函数 它根据我指定的框架和字符串清楚地绘制文本 我的代码是 void drawText NSString textToDraw inFram
  • PowerShell 中的变量作用域

    PowerShell 的一个遗憾是函数和脚本块是动态作用域的 但另一件事让我感到惊讶的是 变量在内部作用域内表现为写时复制 array g function foo array h Write Host array array s Writ
  • UITableViewCell显示多种字体

    我想在 uitableviewcell 中以类似于 iPhone 地址簿的不同字体显示两个单词 例如 约翰Buchanan 您应该使用两个 UILable 或者您可以使用OH属性标签 https github com AliSoftware
  • TableViewController 的 viewDidLoad 未触发

    我一直在关注这个tutorial http www appcoda com ios programming sidebar navigation menu 有一个滑出式菜单 我添加了一个 TableViewController 它将显示文章
  • 在实例化对象之前是否可以检查故事板中是否存在标识符?

    在我的代码中我有这一行 但我想知道是否有办法检查是否 一些控制器 在我将它与 一起使用之前就存在实例化ViewControllerWithIdentifier 方法 如果标识符不存在 则应用程序崩溃 如果没有好的方法 这并不是一个大问题 我
  • 如何在 UICollectionView 中将行居中?

    我有一个UICollectionView与随机细胞 有什么方法可以让我将行居中吗 默认情况下它是这样的 x x x x x x x x x x x x x x 这是所需的布局 x x x x x x x x x x x x 我必须做这样的事
  • 处理 UICollectionView 中的点击手势

    由于我无法使用任何框架来创建相册 因此我尝试使用 Collection View 创建自己的相册 但我一开始就陷入困境 我的目标是将网络服务中的所有图像显示到我的集合视图中 因为所有图像都已显示 下一步是当有人点击任何单元格时 我可以在新视
  • 如何为 UIImageView 随机化器实现滑动手势

    我一直在浏览大量的教程和问题 但似乎找不到我要找的东西 我有一种感觉 我只是错过了一个简单的步骤 我仍在学习诀窍 所以请承受和我一起做这个 我正在 xcode 4 3 3 上制作图像随机化器 并且我已经能够使用按钮来随机化图像 但我希望它能
  • ios - 如何声明静态变量? [复制]

    这个问题在这里已经有答案了 C 中声明的静态变量如下 private const string Host http 80dfgf7c22634nbbfb82339d46 cloudapp net private const string S

随机推荐