2013-03-14 12 views
37

So che ci sono diversi modi di ritardare un'azione in Objective-C come:Objective-C con blocchi

performSelector:withObject:afterDelay: 

o utilizzando NSTimer.

Ma c'è una cosa di fantasia chiamato blocchi in cui è possibile fare qualcosa di simile:

[UIView animateWithDuration:1.50 delay:0 options:(UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState) animations:^{ 

    }completion:^(BOOL finished){ 
}]; 

Purtroppo, questo metodo si applica solo per animare le cose.

Come si crea un ritardo con un blocco in un metodo quindi non è necessario utilizzare tutti coloro @selectors e senza la necessità di creare un nuovo metodo separata? Grazie!

+0

Sarà questo aiuto? http://stackoverflow.com/questions/15218861/call-function-only-after-reloaddata-has-finished/15218941#15218941 –

+0

perché hai paura di creare un metodo separato? questo risolverà il problema immediatamente. – Raptor

+0

@ShivanRaptor perché ho già molti metodi e volevo trovare un modo migliore –

risposta

113

uso dispatch_after:

double delayInSeconds = 2.0; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    //code to be executed on the main queue after delay 
    [self doSometingWithObject:obj1 andAnotherObject:obj2]; 
}); 
+0

eh, tutte queste cose di "spedizione" sono diventate così popolari ... – Stas

+0

bene migliora molto la leggibilità - specialmente quando si usano i blocchi come parametri di metodo –

+4

Sarebbe bello nascondere questo (specialmente il calcolo di 'popTime') in una funzione/metodo, ad esempio '[NSObject performBlock: afterDelay:];' – Sulthan

21

Ampliando la risposta accettata, ho creato una funzione di supporto per tutti coloro che non si preoccupa di memorizzare la sintassi ogni volta che vogliono fare questo :) Ho semplicemente un Utils classe con questo:

Usage:

[Utils delayCallback:^{ 
    //--- code here 
} forTotalSeconds:0.3]; 

metodo di supporto:

+ (void) delayCallback: (void(^)(void))callback forTotalSeconds: (double)delayInSeconds{ 

    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
      if(callback){ 
       callback(); 
      } 
     }); 
} 
2

Ecco come è possibile attivare un blocco dopo un ritardo a Swift:

runThisAfterDelay(seconds: 4) {() ->() in 
    print("Prints this 4 seconds later in main queue") 
    // Or just call animatedMyObject() right here 
} 

/// EZSwiftExtensions 
func runThisAfterDelay(seconds seconds: Double, after:() ->()) { 
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC))) 
    dispatch_after(time, dispatch_get_main_queue(), after) 
} 

La sua incluso come funzione standard nel mio repo: https://github.com/goktugyil/EZSwiftExtensions

Problemi correlati