2013-03-07 9 views
6

Próbowałem zrozumieć, jak działa pamięć podręczna UIWebView. Ponieważ mój cel to , aby móc zarządzać pamięcią przydzieloną przez UIWebView (przynajmniej w miarę możliwości), aby uniknąć zwiększania pamięci w nieskończoność, a aplikacja zostanie zabita z tego powodu.Zapobieganie wyświetlaniu przez UIWebView pamięci w nieskończoność (prawdopodobnie NSURLCache nie działa)

Po readingotherstackoverflowquestions i searchingtheweb, postanowiłem spróbować NSURLCache sharedURLCache, ale nie mogę dowiedzieć się, jak to naprawdę działa.

Moje badania scenariusz jest taki:

I wdrożyliśmy aplikację testową dla iOS 5 gdzie mam pojedynczy widok z UIWebView wewnątrz. Ten UIWebView ma załadować plik lokalny index.html takiego:

// Create an NSString from the local HTML file 
NSString *fullURL = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"www"]; 
NSURL *url = [NSURL fileURLWithPath:fullURL]; 
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; 
// Load local HTML file 
[self.webView loadRequest:requestObj]; 

W tym index.html pliku, Mam skrypt JS, który pobiera JSON z Flickr z ostatnich zdjęć przesłanych do ich publiczny kanał. Każdy obraz jest dołączany do listy. Cały proces powtarza się co sekundę, aż osiągniemy 1000 zdjęć pobranych z kanału. Patrz kod:

var nImg = 0; 

function getData() 
{ 
    $.getJSON('http://api.flickr.com/services/feeds/photos_public.gne?format=json&jsoncallback=?', function(data) 
    { 
     var items = []; 
     $.each(data.items, function(i, image) { 
      items.push('<li id="' + image.title + '"><img src="' + image.media.m + '"/></li>'); 
     }); 
     $('#page > #imagesList').append(items.join'')); 
     nImg += items.length; 
    }); 
    $('#page > #numImages').html(nImg); 

    if(nImg < 1000) 
     setTimeout("getData();", 1000); // Get more data in 1s 
} 

$(document).ready(function() 
{ 
    getData(); 
}); 

Wreszcie w moim AppDelegate, założyłem ten sharedURLCache jak napisano w tym post:

// Initialize the Cache, so we can control the amount of memory it utilizes 
int cacheSizeMemory = 4*1024*1024; // 4MB 
int cacheSizeDisk = 32*1024*1024; // 32MB 
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:nil]; 

[NSURLCache setSharedURLCache:sharedCache]; 

, ale pomimo to, co ma się wydarzyć, gdy otwieram instrumentów i uruchom aplikację sprawdzającą alokacje, pamięć rośnie, podczas gdy my pobieramy obrazy (do 20 MB), zamiast spłaszczać około 4-6 MB, jak można się było spodziewać, gdyby UIWebView używał tego współdzielonego kolażuURL do buforowania pobranych obrazów.

Instruments evolution after we reach 1000 images

Czy ktoś wie co robię źle? Czy coś źle zrozumiałem? Czy źle ładuję stronę? Czy UIWebView używa innej pamięci podręcznej dla obrazów załadowanych w JS?

Proszę, daj mi znać swoje myśli. Naprawdę muszę zrozumieć, jak działa ten współużytkowanyURLCache i jak UIWebView używa go do buforowania URLRequest, obrazów, ... na wypadek, gdyby był w ogóle używany. Nie chcę mieć aplikacji korzystającej z interfejsu UIWebView, która może przydzielić pamięć bez kontroli.

Odpowiedz

1

Jak podążałeś z tym w końcu? Zauważyłem, że twój *sharedCache initWithMemoryCapacity ma argument diskPath, który jest nil.

Z doco Apple:

w iOS, ścieżka jest nazwą podkatalogu domyślnym katalogu pamięci podręcznej aplikacji, w którym przechowywane w pamięci podręcznej na dysku (podkatalog jest tworzony jeśli to robi nie istnieje).

Zamówienie ten link przez Two Bit Labs, w jaki sposób korzystać z cache: http://twobitlabs.com/2012/01/ios-ipad-iphone-nsurlcache-uiwebview-memory-utilization/

Konfiguracja współużytkowanej pamięci podręcznej

Po pierwsze, niech skonfigurować pamięć podręczną podczas uruchamiania aplikacji (przed wszelkie wnioski są wykonane), dzięki czemu możemy kontrolować ilość pamięci, którą wykorzystuje. W swojej UIApplicationDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    int cacheSizeMemory = 4*1024*1024; // 4MB 
    int cacheSizeDisk = 32*1024*1024; // 32MB 
    NSURLCache *sharedCache = [[[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"] autorelease]; 
    [NSURLCache setSharedURLCache:sharedCache]; 
... 

Powyższy konfiguruje 4MB cache w pamięci podręcznej dysku z 32MB. Pamięć podręczna dysku będzie znajdować się w domyślnym katalogu pamięci podręcznej systemu iOS w podkatalogu o nazwie "nsurlcache".

Odpowiadając na ostrzeżenia pamięci

Najczęstszą przyczyną wypadków widzieliśmy w aplikacjach wykorzystujących widoki internetowych jest wyrzucana za nie zwalniając wystarczająco dużo pamięci, gdy przychodzi ostrzeżenie pamięć. Kiedy aplikacja odbiera pamięć ostrzeżenie, należy wyczyścić udostępnioną pamięć podręczną, aby zwolnić pamięć. Czy to w UIApplicationDelegate:

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { 
    [[NSURLCache sharedURLCache] removeAllCachedResponses]; 
} 

Teraz po uruchomieniu aplikacji w profilera, powinieneś zobaczyć wykorzystanie pamięci spłaszczają się, a jeśli wywoła ostrzeżenie pamięci w symulatorze powinien być widoczny spadek wykorzystania pamięci.

+0

Dzięki za odpowiedź! Nie wiedziałem, o co chodziło, a link, który cytujesz, jest tym samym, który właśnie wykonałem, aby wykonać ten test (widzisz, że podłączyłem go do mojego pytania): $ – veducm

Powiązane problemy