2009-08-08 7 views
5

pamięci problemu wycieku - NSConcreteDatapamięć problemem wycieku przy użyciu NSData w iPhone

// to set tip - photo in photo frame  
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:pathOfThumbNail]]; 
UIImage *cellThumbImg; 
if([data length]>0){ cellThumbImg=[UIImage imageWithData:data];} else { cellThumbImg=[UIImage imageNamed:@"130X90.gif"]; } 
UIImageView *imgView=[[UIImageView alloc]initWithImage:cellThumbImg]; imgView.frame=photoFrame; 
(cellThumbImg.size.height>=58 || cellThumbImg.size.width>=58) ? [imgView setContentMode:UIViewContentModeScaleToFill] : [imgView setContentMode:UIViewContentModeCenter] ; 
[cell.contentView addSubview:imgView]; 
[imgView release]; 

moje pytanie jest bardzo podobne do tego pytania,

iPhone - Memory Leak - NSData dataWithContentsOfUrl & UIWebView

Nawet, Dodałem następujący kod do mojego Aplikacja zakończyła uruchamianie, podana poniżej. Poniższy kod służy do ustawiania pamięci sharedCache o zerowej pojemności. To prawie usunie wyciek NSConcreteData w mojej aplikacji. Jednak wycieki pamięci.

- (void)applicationDidFinishLaunching:(UIApplication *)application {  
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]; 
[NSURLCache setSharedURLCache:sharedCache]; 
[sharedCache release]; 
[window makeKeyAndVisible]; 
} 

Nie mogłem znaleźć żadnego rozwiązania dla tego rodzaju pytania z przepełnienia stosu.

Jeśli możesz odpowiedzieć, będę wdzięczny.

Z góry dziękuję.

+0

Podążyłem ścieżką @Bkaenk i @epatelsaid. Jest jednak ten sam problem, co poniższe pytanie. http://stackoverflow.com/questions/280053/iphone-memory-leak-nsdata-datawithcontentsofurl-uiwebview –

Odpowiedz

7

Miałem problemy z tym również w moim dużym projekcie. Po pracy z inżynierem Apple przy próbie zlokalizowania wycieków, w końcu zapytał główny zespół deweloperów Apple za NSURLConnection. Zasadniczo powiedzieli, że istnieje wewnętrzna pamięć podręczna, która nie jest w ogóle widoczna w NSURLConnection i był to znany problem.

Wyruszyłem więc w poszukiwaniu alternatyw. Znalazłem ASIHTTPConnection (link poniżej), który działa poza siecią CFNetwork. Został zaprojektowany jako zamiennik dla NSURLConnection, a także kilka innych wspaniałych gadżetów, takich jak pobieranie na dysk zamiast pamięci, wznawianie pobierania, wywoływanie pasków postępu itp.

Użyłem go we wszystkich moich projektach i nigdy nie miałem żadnych problemów ani skarg. W odpowiedzi na twoje pytanie, w ten sposób pozbyłem się tych wycieków pamięci.

http://allseeing-i.com/ASIHTTPRequest/

+1

Chociaż jest to zaakceptowana odpowiedź i prawdopodobnie problem z OP został rozwiązany, przeoczyłem prostsze rozwiązanie w odpowiedzi Epatela. Jego odpowiedź powinna być zaakceptowana. – coneybeare

4

Twoja wiadomość o wersji została zapisana nieprawidłowo, wpisano relaese, ale jest to release. Sądzę, że to tylko problem w kodzie, który wpisałeś w tym pytaniu.

Po drugie. Nie potrzebujesz pierwszej wiadomości łańcucha alloc init. Wszystko czego potrzebujesz to:

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]]; 

prawda, nie wiem, czy to połączenie jest rzeczywiście poprawna, ale wiem, że zwraca auto wydany NSData obiekt oznaczający swoje poprzednie alloc init będzie przeciekać.

+0

@Blaenk - Proszę pana, proszę sprawdzić poprawkę w moim pytaniu. Mam ten sam problem. Nawet po zastosowaniu proponowanej logiki znajduję ten sam problem z wyciekiem pamięci. –

10

Masz trzy linie, pozwala rozdzielić je

1. NSData *imageData = [[NSData alloc] init]; 
2. imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]]; 
3. [imageData release]; 

Linia 1: przydzielić i init, nowy NSData. Ten NSData będzie mieć numer referencyjny +1

Linia 2: pobierz dane z Internetu i umieść je w pliku NSData. To ustawia zmienną używaną linię 1 do nowej NSData (który jest ustawiony na autorelease) ukrywa się NSData alloced i inited na linii 1

Linia 3: będzie zwolnić NSData otrzymał on Line 2.

Mogłeś usunąć linia 1 i 3 i po prostu dodać deklaracji zmiennej do linii 2. Ponieważ jest autoreleased będzie uwolnienie przez eventloop później ...

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]]; 

proponuję przeczytać Zarząd pamięci sekcje here

+0

@ePatel - Proszę pana, proszę sprawdzić poprawkę w moim pytaniu. Mam ten sam problem. Nawet po zastosowaniu proponowanej logiki znajduję ten sam problem z wyciekiem pamięci. –

+0

Nit: linia 2 ukrywa właśnie przydzielone/zainicjowane dane obrazu, tworząc nowe. –

+0

Najwyraźniej jestem kretynem, przepraszam. Szukałem tego w twoich komentarzach, ale spudłowałem i zrobiłem złe założenie na podstawie edytowanego pytania ... –

7

Gdy używamy dataWithContentOfURL musimy ująć ją NSAutoReleasePool, jak następuje:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

// ** Your Operations ** 

NSData *data = [NSData dataWithContentsOfURL:someURL]; 

// ** Your Operation ** 

[data autorelease]; 
[pool release]; 

Dotyczy to nawet dla NSURLRequest i NSURLConnection.

Problem dotyczy samego kompilatora, a powyższa metoda jest jedyną metodą rozwiązania problemu.

+1

To jest odpowiedź. Wspaniały. –

+0

Jest to absolutnie błędne. Nie zatrzymałeś obiektu z żadnym z 'retain',' alloc', 'copy',' mutableCopy' lub 'new'. Nie masz prawa "autoreasować" go. Jest to niepoprawne i spowoduje, że twój program zawiedzie gdzieś w dole linii. – user102008

Powiązane problemy