ObjectiveC und JavaScriptCore: Wird die Verwendung dieser Methode zum Aufrufen von CallBacks zu Speicherproblemen führen?
HAFTUNGSAUSSCHLUSS: Dies ist ein langer Beitrag, der sich jedoch als sehr nützlich erweisen kann, wenn Sie sich mit der Verwendung des neuen ObjectiveC JavascriptCore-Frameworks und der asynchronen Codierung zwischen ObjC und JS auseinandersetzen.
Hallo zusammen, ich bin ein Super-Neuling in Objective C und baue eine Javascript-Kommunikationsbibliothek in meine iOS-App ein.
Wie auch immer, ich habe versucht, das neue ObjectiveC JavaScriptCore Framework zu verwenden, das in iOS7 eingeführt wurde. Es ist größtenteils ziemlich großartig, wenn auch bislang recht schlecht dokumentiert.
Es ist wirklich seltsam, Sprachkonventionen zu mischen, aber in gewisser Weise auch zu befreien.
Ich sollte hinzufügen, dass ich natürlich ARC benutze, so dass es sehr hilfreich ist, wenn ich aus der Javascript-Welt komme. Ich habe jedoch eine Frage, die sich speziell auf Probleme mit der Speichernutzung beim Wechsel zwischen ObjectiveC und den JSContext-Rückrufen bezieht. Zum Beispiel, wenn ich eine Funktion in Javascript ausführe, die dann etwas asynchronen Code ausführt und dann zu einem definierten ObjectiveC-Block zurückruft und dann einen definierten JS-Rückruf aufruft ... Ich möchte nur sicherstellen, dass ich es richtig mache (d. H nicht Speicher an einem Ort undicht)!
Nur um die Dinge richtig zu machen (weil ich mich auf die Klasse beziehe)self
um die ObjectiveC callbacks aufzurufen erstelle ich eineweakSelf
so spielt es sich schön mit ARC (referenziert von frage:Wenn Sie sich in diesem Block stark einfangen, führt dies wahrscheinlich zu einem Haltezyklus):
__unsafe_unretained typeof(self) weakSelf = self;
Sagen wir, ich habe eineJSContext
und füge eine Funktion hinzu. Ich möchte, dass diese Funktion eine CallBack-Funktion übernimmt und sie mit "Hallo" als Argument aufruftsowie eine andere Funktion übergeben, als Rückruf. dh
// Add a new JSContext.
JSContext context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Add a function to the context. This function takes a callBack function and calls it back with "Hello"
[context evaluateScript: @"var functionA = function(callBack){
var aMessage = "Foo";
callBack(aMessage, function(message){
/* message should say: Foo Bar */
});
}" ];
// Note, if you try to copy this code, you will have to get rid of the returns in the JS script.
Okay, wir haben also unsere grundlegende JS-Seite. Fügen Sie nun die ObjectiveC-Komplexität hinzu. Ich werde den ersten ObjectiveC CallBack-Block hinzufügen:
context[@"functionB"] = ^(NSString *theMessage, JSValue *theCallBack){
[weakSelf objCFunction:theMessage withCallBack:theCallBack];
};
In der gleichen Klasse passiert das alles, in der ich auch die Methodendefinition habe.Dies ist der Ort, der mir die größte Sorge bereitet:
-(void)objCFunction:(NSString *)message withCallBack:(JSValue *)callBack
{
NSString *concatenatedString = [NSString stringWithFormat:@"%@%@", message, @"Bar"];
[callBack callWithArguments:@[concatenatedString]];
}
Also, wenn ich anrufe:
[context evaluateScript: @"functionA(functionB);" ];
Es sollte die Kette durchlaufen und es tut genau das, was ich von ihm erwarte.
Mein Hauptanliegen ist, dass ich hoffe, dass ich nicht irgendwo entlang dieser Kette einen JSValue erfassen kann, der dann herausläuft.
Jede Hilfe, die mir hilft zu verstehen, wie ARC / die JSMachine diesen Ansatz zum fließenden Aufrufen von Rückrufen zwischen Objective C und Javascript handhaben würde, wäre super wertvoll!
Ich hoffe auch, dass diese Frage anderen da draußen hilft, die mit diesem Framework experimentieren.
Vielen Dank!