Napisałem aplikację do testowania wydajności obrazu w systemie iOS. Wypróbowałem 3 różne widoki, wszystkie wyświetlające ten sam duży plik PNG. Pierwszy to widok, który rysuje za pomocą CGContextDrawImage(). Drugi ustawia self.layer.content. Trzeci to zwykły UIImageView.UIImageView wyświetla DUŻO szybciej niż CG lub CALayer. Ktoś wie dlaczego?
Użyte zdjęcie jest tworzone za pomocą - [UIImage initWithContentsOfData:] i buforowane w viewController. Każdy test wielokrotnie przydziela widok, dodaje go do hierarchii widoków, a następnie usuwa i zwalnia. Czasy są pobierane od początku loadView do viewDidAppear i podawane jako fps (efektywnie, wyświetlaj remisy na sekundę).
Oto wyniki od 1 iPad z systemem 5.1, stosując 912 x 634 nieskalowanego obrazu:
CGContext: 11 fps
CALayer: 10 fps
UIImageView: 430 fps (!)
Am I halucynacje? Wydaje się prawie niemożliwe, że UIImageView może pobierać tak szybko, ale faktycznie mogę oglądać migotanie obrazów. Próbowałem zamieniać między dwoma podobnymi widokami, aby pokonać możliwe buforowanie, ale szybkość klatek była jeszcze wyższa.
Zawsze zakładałem, że UIImageView było tylko opakowaniem dla - [CALayer setContent]. Jednak profilowanie UIImageView pokazuje prawie brak czasu spędzonego na dowolnej metodzie rysowania, którą mogę zidentyfikować.
Chciałbym zrozumieć, co się dzieje. Każda pomoc będzie najbardziej ceniona.
Edytuj swoje pytanie, dołączając kod, którego czas dotyczył w każdym przypadku, lub link do niego. –
Kod jest częścią większej aplikacji używanej do testowania naszego zastrzeżonego kodu gry. Zajmie to kilka godzin, aby wyciągnąć odpowiednie fragmenty. W międzyczasie z przyjemnością odpowiem na wszelkie szczegóły, których brakuje w powyższym opisie. –
"Czasy są pobierane od początku loadView do viewDidAppear" - to wydaje się trochę fałszywe, ponieważ 'viewDidAppear' może zostać wywołany, zanim widok faktycznie pojawi się na ekranie.Jeśli nie zmuszasz ekranu do aktualizacji, nie jesteś w stanie wyczuć niczego użytecznego; możesz utworzyć i zniszczyć kilka UIImageViews, ale tylko jeden zostanie narysowany. Zastanawiam się, czy UIImageView ustawia zawartość swojej warstwy na żądanie w "-layoutSubviews" - to na pewno ja bym to zrobił, aby upewnić się, że dotknąłem warstwy tylko raz na aktualizację ekranu. –