2015-02-23 2 views
0

Я использую NSNotificationcentre для обновления пользовательского интерфейса из цикла for. Пользовательский интерфейс не обновляется, пока выполнение не выходит из цикла. Есть ли способ справиться с этим делом? Вот мой код ниже:Обработка обновления пользовательского интерфейса в цикле for - iOS

- (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]; 

updatepreview: класс определен ниже:

-(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]; 

} 

ответ

2

Поскольку цикл for работает по основному потоку, этот поток блокируется до тех пор, пока внешний вид не будет завершен. Поскольку основной угрозой является также поток пользовательского интерфейса, обновленный пользовательский интерфейс не выполняется до тех пор, пока цикл не будет завершен.

Вы должны запустить цикл в фоновом потоке, а изменения пользовательского интерфейса должны быть запущены асинхронно в основном потоке.

И в вашем updatePreviewView: убедитесь, что код будет работать в основном потоке.

1

ли это:

-(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]; 
    }); 
} 
1

Вы должны принять его в основном потоке. Но 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]; 
}); 
Смежные вопросы