ObjectiveC i JavaScriptCore: Czy użycie tej metody wywoływania CallBacków spowoduje problemy z pamięcią?
ZASTRZEŻENIE: Jest to długi post, ale może okazać się bardzo cenny dla tych, którzy zmagają się z użyciem nowej struktury ObjectiveC JavascriptCore i wykonują asynchroniczne kodowanie między ObjC i JS.
Cześć, jestem super nowy w Objective C i integruję bibliotekę komunikacyjną javascript z moją aplikacją na iOS.
W każdym razie próbowałem swoich sił w użyciu nowej struktury ObjectiveC JavaScriptCore wprowadzonej w iOS7. W większości jest to niesamowite, choć do tej pory słabo udokumentowane.
To naprawdę dziwne miksowanie konwencji językowych, ale także w pewien sposób wyzwalanie.
Powinienem dodać, że oczywiście korzystam z ARC, więc to bardzo pomaga w świecie Javascript. Ale mam pytanie, które jest dość specyficzne w odniesieniu do problemów z używaniem pamięci podczas przenoszenia między obiektami CallBack ObjectiveC i JSContext. Na przykład, jeśli wykonam funkcję w JavaScript, która następnie wykonuje jakiś asynchroniczny kod, a następnie wywołuje z powrotem do zdefiniowanego bloku ObjectiveC, a następnie wywołuje zdefiniowane wywołanie zwrotne JS ... Chcę tylko upewnić się, że robię to poprawnie (tj. , nie przecieka pamięci trochę miejsca)!
Po prostu rób rzeczy właściwe (ponieważ odwołuję się do klasy)self
zadzwonić do funkcji ObjectiveC callBacksweakSelf
więc gra dobrze z ARC (na podstawie pytania:silne przechwycenie siebie w tym bloku może doprowadzić do zatrzymania cyklu):
__unsafe_unretained typeof(self) weakSelf = self;
Teraz powiedz, że mamJSContext
i dodaj do niego funkcję. Chcę, aby ta funkcja korzystała z funkcji callBack i nazywała ją argumentem „Hello”jak również przekazać INNĄ funkcję jako oddzwanianie. to znaczy.
// 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.
Dobra, więc mamy naszą podstawową stronę JS. Teraz dodaj złożoność ObjectiveC. Dodam pierwszy blok ObjectiveC CallBack:
context[@"functionB"] = ^(NSString *theMessage, JSValue *theCallBack){
[weakSelf objCFunction:theMessage withCallBack:theCallBack];
};
W tej samej klasie wszystko to się dzieje, mam też definicję metody.To jest miejsce, które najbardziej mnie niepokoi:
-(void)objCFunction:(NSString *)message withCallBack:(JSValue *)callBack
{
NSString *concatenatedString = [NSString stringWithFormat:@"%@%@", message, @"Bar"];
[callBack callWithArguments:@[concatenatedString]];
}
Więc kiedy dzwonię:
[context evaluateScript: @"functionA(functionB);" ];
Powinien przejść przez łańcuch i robi dokładnie to, czego oczekuję.
Moim głównym zmartwieniem jest to, że mam nadzieję, że w jakiś sposób nie uchwycę JSValue gdzieś wzdłuż tego łańcucha, który następnie wycieka.
Jakakolwiek pomoc w zrozumieniu, w jaki sposób ARC / JSMachine poradziłby sobie z płynnym wywoływaniem funkcji callBacks między Objective C i Javascript, byłaby bardzo cenna!
Mam również nadzieję, że to pytanie pomoże innym, którzy eksperymentują z tymi ramami.
Dzięki!