在 for 循环中处理 UI 更新 - iOS

Handling UI update in a for loop - iOS

我正在使用 NSNotificationcentre 从 for 循环更新 UI。 UI 在执行退出循环之前不会更新。有办法处理这种情况吗? 下面是我的代码:

- (void)uploadContent{
    NSURLResponse *res = nil;
    NSError *err = nil;



    for (int i = 0; i < self.requestArray.count; i++) {

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [[NSNotificationCenter defaultCenter] postNotificationName:kUpdatePreviewImageView object:nil userInfo:@{@"image":     [self.imageArray objectAtIndex:i],@"count":[NSNumber numberWithInt:i],@"progress":[NSNumber numberWithFloat:0.5f]}];
        }];
        ImageUploadRequest *request = [self.requestArray objectAtIndex:i];


        NSData *data = [NSURLConnection sendSynchronousRequest:request.urlRequest returningResponse:&res error:&err];
        if (err) {

            NSLog(@"error:%@", err.localizedDescription);
        }
        NSError *jsonError;
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&jsonError];

        NSLog(@"current thread %@",[NSThread currentThread]);

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [[NSNotificationCenter defaultCenter] postNotificationName:kUpdatePreviewImageView object:nil userInfo:@{@"image":[self.imageArray objectAtIndex:i],@"count":[NSNumber numberWithInt:i],@"progress":[NSNumber numberWithFloat:1.0f]}];
        }];
    }


    [[NSNotificationCenter defaultCenter] postNotificationName:kImageUploaded object:nil];


}

在我的 viewcontroller.m 文件中,我在 viewdidLoad()

下声明了观察者
[[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(updatePreviewView:) name:kUpdatePreviewImageView object:nil];

更新预览:class定义如下:

-(void)updatePreviewView:(NSNotification *)notify{


    NSDictionary *previewImageDetails = [notify userInfo];

    self.previewImageView.image = previewImageDetails[@"image"];



    hud.labelText = [NSString stringWithFormat:@"Uploading media %@ of %lu",previewImageDetails[@"count"],(long unsigned)self.mediaDetail.count];


    hud.progress = [previewImageDetails[@"progress"] floatValue];

}

由于 for 循环是 运行主线程,该线程会被阻塞,直到 for 查找完成。由于主要威胁也是 UI 线程,您的 UI 更新在循环完成之前不会完成。

您应该 运行 后台线程上的循环和 UI 更改应该是 运行 主线程上的异步。

并在您的 updatePreviewView: 中确保代码 运行 在主线程上。

这样做:

-(void)updatePreviewView:(NSNotification *)notify{

    dispatch_async(dispatch_get_main_queue(), ^{
        NSDictionary *previewImageDetails = [notify userInfo];
        self.previewImageView.image = previewImageDetails[@"image"];
        hud.labelText = [NSString stringWithFormat:@"Uploading media %@ of %lu",previewImageDetails[@"count"],(long unsigned)self.mediaDetail.count];
        hud.progress = [previewImageDetails[@"progress"] floatValue];
    });
}

你应该把它放在主线程中。但是 NSOperationQueue 可能不会在 for 循环中发送所有内容。您可以在异步队列中进行操作并在没有 NSOperationQueue

的情况下发送它
      dispatch_async(dispatch_get_main_queue(), ^{
  NSDictionary *previewImageDetails = [notify userInfo];
    self.previewImageView.image = previewImageDetails[@"image"];
    hud.labelText = [NSString stringWithFormat:@"Uploading media %@ of %lu",previewImageDetails[@"count"],(long unsigned)self.mediaDetail.count];

    hud.progress = [previewImageDetails[@"progress"] floatValue];
});