2012-08-05 18 views
10

Próbuję naprawić kilka przecieków, które powoduje mój UIWebView i nie można znaleźć ich pochodzenia ani obejścia. Co mogę zrobić, to uzyskiwanie niektóre treści z sieci za pomocą polecenia sieciowego, a następnie zmontować mój HTML i załadować go w locie:Wycieki pamięci za pomocą UIWebView i Javascript

NSString* body = <some HTML>; 
NSString* html = [NSString stringWithFormat:kHTMLTemplate, [self scripts], [self styles], body]; 
[_webView loadHTMLString:html 
       baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]]; 

każdym razem jest dostępna nowa treść, mogę wykonać loadHTMLString ponownie, aby odświeżyć widok internetową . Ponownie używam tego samego widoku internetowego, tego samego kontrolera, tego samego wszystkiego.

Instruments wykazuje bardzo dziwny wzór, w którym wszystkie obiekty są wyciekły Ogólne bloki o różnych rozmiarach i żaden z nich wszelkie informacje z nim związane: brak odpowiedzialnego biblioteka, nie odpowiedzialny ramki, itp Każdy czas jest wykonywany loadHTMLString , nowe przecieki są dodawane.

Wygląda na to, że istnieje kilka wątków w S.O. około UIWebView wyciek pamięci. Próbowałem wszystkich znalezionych sugestii (np. Ustawiającna zero lub resetując go, próbowałem zwolnić istniejący interfejs UIWebView i przydzielić nowe za każdym razem, gdy mam nowe dane itd.), Ale nic nie pomogło.

Moje dochodzenia do tej pory prowadzą do jednoznacznego wyniku: wydaje się, że wycieki są obecne tylko wtedy, gdy HTML załadowany do widoku zawiera trochę kodu Javascript. Jeśli zauważysz powyższy ciąg html, składa się on z kilku komponentów; jeden jest [self scripts] która to funkcja, która zwraca po prostu:

return @"<script type='text/javascript' src='jquery-1.4.4.min.js'></script>" 
     "<script type='text/javascript' src='jmy.js'></script>"; 

Jeśli usunąć ten brak przecieków istnieją. Ale przecieki pojawiają się, gdy dodam znacznik <script> do mojego kodu HTML. nawet jeśli pojawiają się one po prostu dołączyć plik jquery (lub dowolny inny plik js, jak do tego):

return @"<script type='text/javascript' src='jquery-1.4.4.min.js'></script>"; 

Więc pytanie: ma ktoś pomysł o tym, co się tu dzieje? Oczywiście włączenie pliku JavaScript do mojego kodu HTML powoduje, że pamięć wycieku UIWebView jest niedostępna.

Fakt, że pojawiają się przecieki zarówno kiedy używać tego samego UIWebView obiektu lub kiedy wystąpienie nowego jeden za każdym razem mam treści, skłania mnie do myślenia, że ​​coś musi być w sposób pliki JavaScript są obsługiwane przez loadHTMLString co prowadzi do przecieków.

Czy ktoś wie, jak to naprawić?

enter image description here

+0

To może być błąd w usłudze UIWebView. http://blog.techno-barje.fr/post/2010/10/04/UIWebView-secrets-part1-memory-leaks-on-xmlhttprequest/ –

+0

@ H2CO3: dzięki, spróbowałem też ... bez ulepszeń. .. – sergio

+0

Myślę, że jesteśmy zapisywani przez iOS 8. Sprawdź tę odpowiedź na WKWebView http://stackoverflow.com/questions/16514230/massive-memory-leak-in-ios-uiwebview –

Odpowiedz

11

końcu znalazłem trochę pojęcia, co się dzieje, a przede wszystkim obejście że chciałbym się podzielić.

Mogę potwierdzić, że proste włączenie niektórych plików javascript spowodowało wyciek pamięci po przeładowaniu widoku WWW. Próbowałem nawet zbudować plik z zawartością HTML, a następnie załadować go do UIWebView do loadRequest i ponownie załadować go przez reload; przecieki były zawsze tam. Wezwę do tego radar.

To, co mnie uratowało, to zaktualizowanie zawartości widoku internetowego za pomocą innerHTML.Zamiast polegać na reload lub loadHTMLString, ja zainicjowany mój pogląd internetową z pustym korpusie (mam na myśli, sekcja head tam, w tym wszystkie wymagane JS/plików CSS), a następnie zaktualizowane to ustawienie document.body.innerHTML:

body = [body stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; 
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setBody(\"%@\");", body]]; 

z setBody zdefiniowane tak:

var setBody = function(body) { 
    document.body.innerHTML = body; 
} 

zdobyłem dwie korzyści: aktualizacja Zobacz Web stał się bardzo szybko (jest to efekt nie aktualizując dom, który z drugiej strony nie jest do końca pożądane w całości), a tam nie było wycieków pamięci uruchomiono aplikację w ramach Instruments. Wadą było to, że musiałem dopracować kilka warunków, w których aplikacja działała dobrze; w szczególności:

  1. ładowania widok internetową (nawet z pustym stronie ciała) podejmuje się wiele, więc trzeba zsynchronizować pierwszą aktualizację jej treści do kiedy DOM jest gotowy;

  2. webViewDidFinishLoading nie wydaje się wiarygodne: jest on wykonywany przed document.readyState staje complete;

  3. document.documentElement.height, oficjalny sposób pobierania wysokość strony nie wydaje się wiarygodne, zbyt: obejście jest uzyskanie „komputerowej stylu” z body części i odczytać jego wartość height.

Mam nadzieję, że pomoże to komuś innemu, kto odkryje, że jego wyświetlenia w sieci są przeciekające.

Powiązane problemy