2014-12-12 8 views
5

Stworzyłem aplikację i jest ona (dobrze) gotowa do przesłania.Ostrzeżenia i awarie pamięci ImageIO-jpeg-dane

Ta aplikacja to w zasadzie aplikacje do kart flash dla dzieci, w których jest 12 kart na stronę.

Jest to obecnie tylko iPad i po dotknięciu karty obraz jest animowany z karty na pełny ekran z pełną rozdzielczością 2048 x 1536 i odtwarza dźwięk zwierzęcia, dotykasz obrazu w pełnym rozmiarze i wraca na kartę. Każda karta ma przypisane 5 obrazów. Aplikacja działa doskonale przez cały okres projektowania i teraz, gdy załadowałem wszystkie zwierzęta i testowałem je i zauważyłem, że się zawiesił.

Krótko mówiąc, pamięć stale rośnie o 12 MB na obraz (chociaż każdy obraz ma około 200-400 KB), aż osiągnie 700 MB pamięci i ulega awarii. Ta pamięć nigdy się nie zmniejsza.

Uruchomiłem aplikację za pomocą instrumentów xcode i nie widzę żadnych wycieków, ale w "Przydziałach" stwierdzono, że jest to kategoria "ImageIO-jpeg-data", która jest winowajcą.

Spędziłem cały wieczór na czytaniu o tym, ponieważ znalazłem obiecujące wyniki, jednak te wyniki nie sprawdziły się, więc zakładam, że źle zrozumiałem, co zostało poradzone lub nie zrozumiałem, więc miałem nadzieję, że ktoś może może mi pomóc lub wyjaśnić laikom, w jaki sposób mogę rozwiązać ten problem.

OK, aby wyjaśnić, w jaki sposób skonfigurowałem widok.

Pierwotnie ustawiłem 5 obrazów dla każdej karty w tablicy, ale było opóźnienie, więc ktoś tutaj zalecił załadowanie obrazów w viewDidLoad, a następnie wywołanie ich po dotknięciu karty/przycisku.

Tak na przykład używałem tego formatu w viewDidLoad

domestic100 = [UIImage imageNamed:@"ferret-00"]; 
domestic101 = [UIImage imageNamed:@"ferret-01"]; 
domestic102 = [UIImage imageNamed:@"ferret-02"]; 
domestic103 = [UIImage imageNamed:@"ferret-03"]; 
domestic104 = [UIImage imageNamed:@"ferret-04"]; 

a następnie w przycisk wciśnięty I przypisany obrazu w widoku obrazu poprzez wywołanie:

domestic01ImageContainer.image = domestic100; 

Wewnątrz czy inny sprawdź, czy numer obrazu był od 1 do 4.

W każdym razie działało idealnie (oprócz tego problemu z pamięcią)

Czytałem w Internecie, że będę lepiej deklarowania uiimages użyciu

[UIImage imageWithContentsOfFile:path] 

jak widać w tym poście: UIImage memory not deallocating VM: ImageIO_JPEG_DATA?

Tak więc zmiany, jakie dokonane w kodzie są:

w moim viewDidLoad i teraz tworzyć uiimages jak tak:

domestic200 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-00" ofType: @"jpg"]]; 
domestic201 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-01" ofType: @"jpg"]]; 
domestic202 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-02" ofType: @"jpg"]]; 
domestic203 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-03" ofType: @"jpg"]]; 
domestic204 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-04" ofType: @"jpg"]]; 

a następnie w przycisk tłoczony wywołać obraz się do ImageView wykorzystaniem

[domestic01ImageContainer setImage:domestic100]; 

Dostaję takie same wyniki - obraz dopiero buduje w tej samej pamięci i nie zwalniając ani dealokując.

Nie jestem czarodziejem, jeśli chodzi o cel c - to moja pierwsza prawdziwa aplikacja.

Jeśli ktoś mógłby być na tyle uprzejmy, aby poświęcić chwilę swojego czasu, aby mi pomóc, byłbym naprawdę wdzięczny.

Z góry dziękuję.

****** Edit ******

Dlatego powiedziałem wam, jak załadować moje obrazy powyżej, ja też w viewDidLoad dać 12 imageviews punkt początkowy i ukryty alfa.

domestic01ImageContainer = [[UIImageView alloc] initWithFrame:CGRectMake(30, 123, 152, 224)]; 
domestic01ImageContainer.Alpha = 0; 

Następnie dodać podrzędny z:

[self.view addSubview:domestic01ImageContainer]; 

każdy ImageView przeznaczono gest z kranu, aby ukryć obraz w późniejszym punkcie:

UITapGestureRecognizer *domestic01Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTaped:)]; 
[domestic01ImageContainer addGestureRecognizer:domestic01Tap]; 
[domestic01ImageContainer setUserInteractionEnabled:YES]; 

Gdy kciuk/karty jest naciśnięcie usprawnionej wersji przycisku byłoby następujące:

- (IBAction)domestic01ButtonClicked:(id)sender { 
static int imageNumber = 0; 

if (imageNumber == 0) { 
    [domestic01ImageContainer setImage:domestic100]; 
    imageNumber++; 
} 

else if (imageNumber == 1) { 
    [domestic01ImageContainer setImage:domestic101]; 
    imageNumber++; 
} 

else if (imageNumber == 2) { 
    [domestic01ImageContainer setImage:domestic102]; 
    imageNumber++; 
} 

else if (imageNumber == 3) { 
    [domestic01ImageContainer setImage:domestic103]; 
    imageNumber++; 

} 

else if (imageNumber == 4) { 
    [domestic01ImageContainer setImage:domestic104]; 
    imageNumber = 0; 
} 

domestic01ImageContainer.Alpha = 1; 

[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 
     domestic01ImageContainer.frame = CGRectMake(0, 0, 768, 1024); 
    } completion:^(BOOL finished) { 

}]; 

}

in moim imageTapped rozpoznawania się kurczyć w pełnym rozmiarze z powrotem na kartę używać:

[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 
     domestic01ImageContainer.frame = CGRectMake(30, 123, 152, 224); 
    } completion:^(BOOL finished) { 
     domestic01ImageContainer.Alpha = 0; 
    }]; 

które w zasadzie umieścić kartę pamięci flash z powrotem z pełnego ekranu do rozmiaru karty/miniatury i ustawia alfa ponownie na 0.

Tak jak powiedziałem, wszystko działa, ale jak sugerujesz, obraz jest gdzieś zatrzymany.

Mam nadzieję, że to rzuci nieco więcej światła na to, co może być przyczyną problemu.

Próbowałem ustawić obraz na zero po tym, jak alfa było ustawione na 0 w obrazie, ale to nie wyczyściło pamięci.

+0

Wygląda na to, że obrazy są przechowywane w miejscu, którego się nie spodziewasz. Czy przypisujesz obrazy do więcej niż jednej zmiennej lub właściwości? –

+0

Cześć Anna, dodam do mojego komentarza, żebyś miał więcej informacji. Dzięki –

+0

Ile zdjęć załadowałeś w danym momencie? Nie mogę powiedzieć z twojego opisu. Jeśli masz jednocześnie załadowanych 12 x 5 obrazów, to 750 MB. Należy pamiętać, że obrazy są * nieskompresowane * po przypisaniu ich do obrazu, a obrazy mają po 12,5 MB. Musisz opóźnić ładowanie obrazów, dopóki nie będą potrzebne. –

Odpowiedz

1

Miałem podobny problem. Pamięć była trzymana nienormalnie. Miałem UIImageView IBOutlet i ustawiłem jego właściwość image z właściwością UIImage kontrolera widoku, którą ustawiłbym podczas inicjowania kontrolera widoku. UIImageView niesłusznie trzymałby właściwość UIImage kontrolera widoku, nawet gdybym wrócił do kontrolera widoku głównego.

Naprawiłem problem poprzez zmianę właściwości kontrolera widoku za UIImage do NSData i ustawienie właściwości obrazu UIImageView w następujący sposób:

[_previewImageView setImage:[UIImage imageWithData:_previewImageData]]; 

Ten problem został rozwiązany z ImageIO-JPEG danych jest pomoc na niepotrzebnie. Mam nadzieję, że to pomaga komuś.

Powiązane problemy