JavaScriptCore sa iOS-om

12 views
Skip to first unread message

kresimir prcela

unread,
May 10, 2013, 3:11:20 AM5/10/13
to mobd...@googlegroups.com
Nedavno sam imao ovaj problem, a zaboravio sam ga postati i ovdje.

Dakle, koristim JavaScriptCore (JSC) library u iOS aplikaciji koji uredno učitava i izvršava javascript fileove. Radi odlično. Međutim problem je kada iz JSC-a pozovem neku native iOS funkciju koja treba odraditi neki asinhroni task. Kada je task gotov, native iOS treba pozvati nazad zadanu js funkciju proslijeđenu iz JSC-a. 
U javascriptu su funkcije ujedno i objekti, pa zbog toga JSC garbage collector pobriše tu zadanu funkciju jer je ona smeće u okviru JSC-a. 


Pisao sam o tome problemu i na stackoverflowu, odgovori su dobri ali još uvijek ne znam šta da radim. Budišu da pitam?

Evo linka:


Na kraju sam odustao od JSC-a i koristio čistu UIWebView kontrolu. Dakle, laički sam odustao od native iOS aplikacije. Nisam išao raditi iznova logiku u objective C-u koja je već napravljena u js-u i ima je mnogoooo.

Nemojte se ubiti da ovo odgovorite, ako neko zna nek kaže.

Ivan Krstić

unread,
May 10, 2013, 3:17:58 AM5/10/13
to mobd...@googlegroups.com
On May 10, 2013, at 12:11 AM, kresimir prcela <kresimi...@gmail.com> wrote:
> U javascriptu su funkcije ujedno i objekti, pa zbog toga JSC garbage collector pobriše tu zadanu funkciju jer je ona smeće u okviru JSC-a.

Ovo je točna dijagnoza; rješenje je upotreba JSValueProtect() i JSValueUnprotect() poziva koji ti daju ručnu kontrolu nad GCom JSValueRef/JSObjectRef tipova.

Pozdrav,
Ivan.

kresimir prcela

unread,
May 10, 2013, 3:47:19 AM5/10/13
to mobd...@googlegroups.com, krs...@solarsail.hcs.harvard.edu
Thanks.

Pokušao sam koristiti i JSValueProtect i nije mi pomoglo. Očito sam negdje fulao.

Nije mi jasan context u kojem je funkcija proslijeđena. 

Kada se iz JSC-a pozove native iOS funkcija, onda JSC proslijedi osim callback funkcije i context. Je li moguće da se onda ta funkcije može izvršavati samo u tom contextu ili se može izvršiti i u globalnom JSC contextu? 

Taj proslijeđeni context postane također invalidan kada je asinhroni task izvršen.

Moguće je da moram koristiti JSvalueProtect i nakon taska pozivati callback js funkciju u globalnom contextu.

Čudni su putovi javascripta. Zbunj. Glup.

damir kolobaric

unread,
May 10, 2013, 3:51:12 AM5/10/13
to mobd...@googlegroups.com
Ovako iz 'neba' prijedlog.

Da si napravis u samoj java scripti, neki globalni dictionary, i u njega spremas funkcije koje ne zelis da ti se izbrisu.
Napravis si neku vrstu registracije/ deregistracije callback funkcija. U tom slucaju GC nece smjeti pocistiti tu funkciju, a ti sam mozes je pocistiti kada je izvrsis.





2013/5/10 kresimir prcela <kresimi...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "iDevHR" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mobdevhr+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

kresimir prcela

unread,
May 10, 2013, 4:38:47 AM5/10/13
to mobd...@googlegroups.com
Thanks. Ovo je isto dobro za isprobati. Malo je workaround ali to bi trebalo raditi.

Odgovor na pitanje "Što ja zapravo želim" su dvije stvari koje svaki web browser podržava, ali ne postoje u JSC-u:

1. setTimeout(callbackFunction, delay)
2. ajax(url, successFunction, errorFunction)

Te funkcije odradi native app i pozove zadane callback funkcije u JSC.

damir kolobaric

unread,
May 10, 2013, 5:01:49 AM5/10/13
to mobd...@googlegroups.com
To je nesto sto ja imam izvedeno u svome krsh 3d enginu. Ne koristim jsc nego standardni webkit.
Jedina interakcija native koda i webkita je koristenje uiwebview stringByEvaluatingJavaScriptFromString,
s tim da ja onda koristim pulling evenata iz skripte.

1. U skripti definiraj si register callbackova, svaki callback neka ima svoj id, i cuvaj ih u nekom arrayu / dictu.
    Mozes si cuvati i parametre funkcije - kao neki array.
2. Moras odluciti kako ces se integrirati sa native kodom, koristenjem jsc a i extendanjem js interfacea, dali koristenjem specijalnog uria i gledanjem shouldLoad... , ili nesto trece (sto sam ja odabrao).
3. kako god da okrenes, u native kodu ces na kraju imati 'setTimeout' funkciju, kojoj ces dati parametare tipa  
   delay i id funtion callbacka.
4. u native kodu odradi delayed akciju, i nakon toga pozoves skriptu tipa
    'onSetTimeoutCb('nekiid'); OnSetTimoutCb je reciomo, js globalna funkcija.
5. u samome JS u potrazi si objekt funkcije, (mozes i parametre spremiti - ljepota dinamickog jezika) i 
   izvrsi funkciju. 
6. obrisi registraciju u js u, da se resourci oslobode.

Ovisno o nacinu intergracije (znam da je to spider monkey mogao, a vjerojatno i JSC moze) ti mozes
pozvati native funkciju i dati joj parametre tipa function pointer. Tada direktno iz samoga native koda mozes
pozvati javascript funkciju koju si dobio kao parametar (vjerujem da tako radi prava implementacija setTimeout a).

Ivan Krstić

unread,
May 11, 2013, 4:17:49 PM5/11/13
to mobd...@googlegroups.com
On May 10, 2013, at 12:47 AM, kresimir prcela <kresimi...@gmail.com> wrote:
> Pokušao sam koristiti i JSValueProtect i nije mi pomoglo. Očito sam negdje fulao. Nije mi jasan context u kojem je funkcija proslijeđena. Kada se iz JSC-a pozove native iOS funkcija, onda JSC proslijedi osim callback funkcije i context. Je li moguće da se onda ta funkcije može izvršavati samo u tom contextu ili se može izvršiti i u globalnom JSC contextu?

Dakle, falile su ti dvije stvari. Prvo, funkciju trebaš zaštititi sa JSValueProtect() kako ne bi bila GC-ana. Drugo, JSContextRef koji dobiješ u callbacku *ne smiješ* nigdje spremiti. Taj je kontekst validan samo za vrijeme tvog callbacka. S obzirom da je funkcija dio globalnog konteksta koji si inicijalizirao, trebaš proslijediti taj globalni kontekst u JSObjectCallAsFunction().

Pozdrav,
Ivan.
Reply all
Reply to author
Forward
0 new messages