2017-02-20 71 views
0

我有一個複雜的操作,那麼當操作完成後,的iOS writeToURL延遲或畫面凍結,如何解決線程的情況下

這將節省的NSData寫入文件預覽。

我遇到一個問題,當我按一下按鈕,

按鈕動作開始表演MBProgress的事情,異步到複雜的背景中運行。

當文件寫入成功時,它會將prepareForSegue方法的傳遞值傳遞給destinationViewController。

我嘗試添加線程,但我發現我的屏幕始終凍結或無法寫入文件成功停留此屏幕顯示警報(我認爲它操作不完整,因此獲得BOOL爲NO)。

如何在這種情況下編寫解決方案以顯示MBProgress等待操作完成,然後導航到下一個viewcontroller?

非常感謝。

我下面的代碼:

- (IBAction)fileBtnAction:(UIButton *)sender{ 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 

    [self doComplexOperateAction]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     fileHud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
     fileHud.label.text = @"file operating...."; 
     fileHud.userInteractionEnabled = NO; 
     }); 
    }); 

} 

- (void) doComplexOperateAction{ 

     ....... do something....... 

     NSError *error; 
writeFileSuccess = [resultFilie.fileContent writeToURL:previewFileUrl 
                 options:NSDataWritingFileProtectionComplete 
                  error:&error]; 
} 

-(BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{ 

if([identifier isEqualToString:@"fileSuccessSegue"]){   
     if(writeFileSuccess == YES){ 
      fileHud.hidden = YES; 
      fileHud = nil; 
      return YES; 
     }else{ 
      dispatch_async(dispatch_get_main_queue(), ^{ 

      msgAlertController.message = @"can't write file success"; 
      [self presentViewController:msgAlertController animated:YES completion:nil]; 
      fileHud.hidden = YES; 
      fileHud = nil; 
     }); 
     return NO; 
    } 
} 
    return NO; 
} 

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 

if([[segue identifier] isEqualToString:@"fileSuccessSegue"]){ 

    ......... 
    NSURL *fileURL = [NSURL fileURLWithPath:fileTmpPathString]; 
    fileSuccessViewController *pfVC = [segue destinationViewController]; 
    pfVC.filePathURL = fileURL; 

} 
} 

回答

0

如果寫入文件或沒有我無法理解。無論如何,請記住,如果您嘗試分派到主線程,則應該首先檢查您是否已經在主線程中,因爲它可能會掛起應用程序。 例子:

if([NSThread isMainThread]){ 
    //perform gui operation 
} else { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     //perfrom gui operation 
    }); 
} 

編輯:你應該考慮使用dispatch_async的dispatch_sync而不是主線程,因爲你已經在嵌套急件 - (IBAction爲)fileBtnAction:(UIButton的*)發件人:

[self doComplexOperateAction]; 

    dispatch_**sync**(dispatch_get_main_queue(), ^{ 
     fileHud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
     fileHud.label.text = @"file operating...."; 
     fileHud.userInteractionEnabled = NO; 
     }); 
    }); 
+0

我的代碼會做一些操作並保存文件。當文件保存成功時,它將導航到下一個uiviewcontroller。所以我想等待文件保存完成,然後代碼將運行prepareforsegue方法導航下一個控制器。但我不知道如何等待文件保存完整的導航到下一個viewcontroller。謝謝 。 – dickfala

+0

編輯我的答案。 –

+0

感謝您的回覆。我嘗試使用dispatch_sync代替主線程的dispatch_asaync,但「writeFileSuccess」值爲NO,不等待保存文件完成,然後轉到prepareforsegue。 – dickfala

0

我認爲這將是這樣的:

@property (noatomic) BOOL uploading; 
- (IBAction)fileBtnAction:(UIButton *)sender{ 

    fileHud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
    fileHud.label.text = @"file operating...."; 
    fileHud.userInteractionEnabled = NO; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
     [self doComplexOperateAction]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      [self performSegueWithIdentifier:@"fileSuccessSegue" sender:nil]; 
     }); 
    }); 

} 

- (void) doComplexOperateAction{ 
    self.uploading = YES; 
    ....... do something....... 

    NSError *error; 
    writeFileSuccess = [resultFilie.fileContent writeToURL:previewFileUrl 
                options:NSDataWritingFileProtectionComplete 
                 error:&error]; 

    self.uploading = NO; 
} 

-(BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{ 

    if([identifier isEqualToString:@"fileSuccessSegue"]){   
     if(writeFileSuccess == YES){ 
      fileHud.hidden = YES; 
      fileHud = nil; 
      return YES; 
     }else{ 
      msgAlertController.message = @"can't write file success"; 
      [self presentViewController:msgAlertController animated:YES completion:nil]; 
      fileHud.hidden = YES; 
      fileHud = nil; 
     }); 
     return NO; 
     } 
    } 
    return !self.uploading; 
} 

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 

    if([[segue identifier] isEqualToString:@"fileSuccessSegue"]){ 

     ......... 
     NSURL *fileURL = [NSURL fileURLWithPath:fileTmpPathString]; 
     fileSuccessViewController *pfVC = [segue destinationViewController]; 
     pfVC.filePathURL = fileURL; 

    } 
} 

我會建議你重寫這段代碼。我不喜歡你如何處理錯誤。因爲writeFileSuccess在您上傳內容時有意想不到的價值。

+0

首先感謝您的迴應。我試試你的固定代碼會顯示警報不等待文件保存完成。我需要等待文件保存成功,然後將URL路徑傳遞給下一個uiviewcontroller。謝謝。 – dickfala

+0

可能是我不明白你需要什麼。我的代碼會在保存文件時顯示MBProgressHUD。文件保存後會執行segue顯示其他視圖控制器。 – Sergey

+0

嗨,謝爾蓋,你的意思是對的。但是我嘗試使用你的方法,它會崩潰。@@ it show [... fileBtnAction:] _ block_invoke – dickfala

相關問題