2015-04-30 28 views
1

我怎樣才能在下面的代碼替換usleepNSTimer用NSTimer替換usleep?

/** 
* DETERMINATE BAR with LABEL 
*/ 

- (void)showDeterminateBarWithLabel:(CDVInvokedUrlCommand *)command { 

    // obtain commands 
    bool dim = [[command.arguments objectAtIndex:0] boolValue]; 
    int increment = [[command.arguments objectAtIndex:1] intValue]; 
    NSNumber* incrementValue = @(increment); 
    NSString* text = [command.arguments objectAtIndex:2]; 

    // initialize indicator with options, text, detail 
    self.progressIndicator = nil; 
    self.progressIndicator = [MBProgressHUD showHUDAddedTo:self.webView.superview animated:YES]; 
    self.progressIndicator.mode = MBProgressHUDModeDeterminateHorizontalBar; 
    self.progressIndicator.labelText = text; 


    // Check for dim : true ? false 
    if (dim == true) { 
     self.progressIndicator.dimBackground = YES; 
    } 

    // Load Progress bar with ::incrementValue 
    [self.progressIndicator showWhileExecuting:@selector(progressTask:) onTarget:self withObject:incrementValue animated:YES]; 

    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@""]; 
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; 
} 

- (void)progressTask:(NSNumber *)increment{ 

    // get increment value 
    int _increment = [increment intValue]; 

    float progress = 0.0f; 
    while (progress < 1.0f) { 
     progress += 0.01f; 
     self.progressIndicator.progress = progress; 

     // increment in microseconds (100000mms = 1s) 
     usleep(_increment); 
    } 
} 

此代碼是從here拍攝。

+0

添加一些上下文可能很有用(即該代碼來自https://github.com/pbernasconi/cordova-progressIndicator/blob/master/src/ios/ProgressIndicator.m#L429,並且是回調方法對於MBProgressHUD)。 「翻譯」這種孤立的方法可能沒有意義。 –

+0

@MartinR謝謝! – confile

回答

1

你不行。這兩個是完全不同的,這段代碼需要阻止操作。 編輯:因爲它在後臺線程上執行。

-progressTask:this method執行的方法,該方法是在一個new thread開始:

- (void)launchExecution { 
    @autoreleasepool { 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
     // Start executing the requested task 
     [targetForExecution performSelector:methodForExecution withObject:objectForExecution]; 
#pragma clang diagnostic pop 
     // Task completed, update view in main thread (note: view operations should 
     // be done only in the main thread) 
     [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO]; 
    } 
} 

它依賴於同步執行,並使用NSTimer將requre開始NSRunLoop並讓它運行了一段時間,這將是實際上可能,但只是不要

提示:如果您更喜歡Objective-C方式,請在幾秒鐘內用參數調用+[NSThread sleepForTimeInterval:]

+0

我只能快速瀏覽MBProgressHUD,並且認爲progressTask:在後臺線程上調用。另外,self.progressIndicator.progress只設置一個屬性。該屬性被觀察到,並且更改「轉發」到主線程。我不打算捍衛這種設計,但我看不到主線程在這裏被阻塞。 –

+0

@MartinR是的 - 該代碼仍然看起來像用戶界面,因此,必須在主線程上。這意味着阻塞對於應用程序的感覺是致命的,充其量也可能導致它被操作系統殺死,如果阻塞時間足夠長的話。 – bbum

+0

@MartinR我沒有提到阻塞主線程,但阻塞了後臺線程。如果你沒有阻止Background Thread(sleep或runloop),它會退出。 – Tricertops

2

總之,你不能用它來阻塞一個線程。阻塞任何類型的睡眠或延遲線程都是不好的設計,應該在極少數情況下避免。

嚴格禁止在iOS/OS X應用程序中阻塞主線程。主循環必須允許運行,否則您的應用程序最多隻會響應不了,最壞的情況是無法運行。

而是使用NSTimer來定期回調代碼以更新值。它不會阻止執行。

+0

給出的代碼只是一個真實任務的模擬。它在後臺線程上執行並且在這種情況下使用睡眠(模擬)是可以接受的。 – Tricertops