Utilizzando la JSContext
da un UIWebView
ho creato una funzione JavaScript che viene implementato come un blocco C Obiettivo:Calling [callWithArguments JSValue:] serrature UI quando alert() viene chiamato
JSContext *js = ... //get contect from web view
js[@"aFunc"] = ^(JSValue *aString, JSValue *callback) {
NSString *realString = [aString toString];
MyOperation *op = [[MyOperation alloc] initWithString:realString andCallback:callback];
//Do some heavy lifting in background
[self.myQueue addOperation:op];
}
Questa funzione richiede un callback come argomento e svolge un lavoro in un NSOperationQueue
prima di chiamare la callback come:
- (void)main {
JSValue *arg = [self theHeavyWork];
//Now we have finished the heavy work, switch back to main thread to run callback (if any).
if ([self.callback isObject] != NO) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.callback callWithArguments:@[arg]];
});
}
}
Questo funziona bene, a meno che il callback contiene una chiamata a alert()
:
//This javascript is part of the page in the UIWebView
window.aFunc("important information", function(arg) { alert("Got " + arg); });
In questo caso, l'avviso viene visualizzato e l'interfaccia utente non risponde più. Suppongo che l'evento che l'evento di tocco per chiudere l'avviso sia bloccato dall'avviso che si trova lì.
Se chiamo il callback senza la spedizione (in altre parole su cui si inserisce sempre lo MyOperation
) funziona perfettamente, ma ho avuto l'impressione che qualsiasi codice che potrebbe avere implicazioni dell'interfaccia utente (in altre parole qualsiasi Callback JS) dovrebbe sempre essere eseguito sul thread principale. Mi manca qualcosa o è davvero impossibile usare in modo sicuro alert()
quando si utilizza il framework JavaScriptCore
?
io non sono sicuro di aver capito la tua domanda. Puoi pubblicare per favore il codice completo che stai citando e descrivere chiaramente cosa succede contro ciò che ti aspettavi che accadesse? –
@AbhiBeckert Modificato come richiesto per rendere un po 'più chiaro il modo in cui gestisco i thread – erm410
È interessante notare che l'accodamento del callback utilizzando [NSObject performSelectorOnMainThread: withObject: waitUntilDone] non sembra causare il deadlock eseguito da dispatch_async. – erm410