objective-c - 从迭代NSMutableArray中删除对象

标签 objective-c ios

根据Best way to remove from NSMutableArray while iterating?,我们不能在迭代时从NSMutableArray中删除对象,是的。

但是,如果我有如下代码,该怎么办

- (void)sendFeedback {
    NSMutableArray *sentFeedback = [NSMutableArray array];
    for (NSMutableDictionary *feedback in self.feedbackQueue){
        NSURL *url = [NSURL URLWithString:@"someApiUrl"];
        ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
        [request setPostValue:[feedback objectForKey:@"data"] forKey:@"data"];
        [request setCompletionBlock:^{
            [sentFeedback addObject:feedback];
        }];
        [request startAsynchronous];
    }
    [self.feedbackQueue removeObjectsInArray:sentFeedback];
}

我正在使用NSRunLoop创建一个NSThread来每隔一段时间执行一次sendFeedback方法。我向api发送数据的方式是使用异​​步方法(该方法将为每个请求创建一个后台线程)发送反馈后,必须将其删除,然后NSRunner在下一次执行此方法以避免重复数据提交。

通过使用异步,循环(主线程)将继续运行,而无需等待服务器的响应。在某些情况下(也许是大多数情况),循环将在每个请求的服务器响应全部返回之前完成运行。如果是这样,则完成块的代码将在 removeObjectsInArray 之后执行,这将导致发送的数据保留在self.feedbackQueue中

我很确定有几种方法可以避免该问题。但是我唯一想到的是使用同步方法,以便在所有请求的响应返回之前(成功或失败),不执行 removeObjectsInArray 。但是,如果这样做,则意味着必须较长时间连接互联网。 sendFeedback的线程所需的时间将更长。即使它将由新创建的NSThread运行,这也不会导致应用程序不响应,反正仍然需要资源。

那么,除了我上面提到的以外,还有其他方法吗?任何建议都欢迎。

谢谢。

最佳答案

有几种方法可以解决此类问题。我建议使用一个调度组来同步您的反馈,并使用一个实例变量来防止新的反馈批仍在进行中。对于此示例,假设您为类创建了一个名为_feedbackUploadInProgress的实例变量,则可以像这样重写-sendFeedback方法:

- (void)sendFeedback
{
  if( _feedbackUploadInProgress ) return;
  _feedbackUploadInProgress = YES;

  dispatch_group_t group = dispatch_group_create();
  NSMutableArray *sentFeedback = [NSMutableArray array];
  for (NSMutableDictionary *feedback in self.feedbackQueue) {
    // enter the group for each item we're uploading
    dispatch_group_enter(group);
    NSURL *url = [NSURL URLWithString:@"someApiUrl"];
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    [request setPostValue:[feedback objectForKey:@"data"] forKey:@"data"];
    [request setCompletionBlock:^{
      [sentFeedback addObject:feedback];
      // signal the group each time we complete one of the feedback items
      dispatch_group_leave(group);
    }];
    [request startAsynchronous];
  }
  // this next block will execute on the specified queue as soon as all the
  // requests complete
  dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    [self.feedbackQueue removeObjectsInArray:sentFeedback];
    _feedbackUploadInProgress = NO;
    dispatch_release(group);
  });
}

关于objective-c - 从迭代NSMutableArray中删除对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10022687/

相关文章:

ios - 以编程方式将视网膜照片分配给 UIButton

ios - CloudKit:备份所有服务器数据?有什么解决办法吗?

asp.net - ASP中AES256加密解密

ios - 在调用完成处理程序后如何处理每个 iOS 后台获取 UIBackgroundFetchResult 类型?

ios - 如何从 react native 页面快速打开现有的ViewController?

objective-c - NSInteger 错误的隐式转换

iphone - 当 UITextField 是第一响应者时,仍然可以选择 UIButton?

ios - 带有 UIToolbar 错误的 UIDatePicker

ios - 收藏 View 图像未显示,但 Url 工作正常

ios - 如何将 UIButton 的标题设置为左对齐?