CGImage / UIImage leniwie ładuje wątek UI powoduje jąkanie
Mój program wyświetla poziomą powierzchnię przewijania wyłożoną kafelkami za pomocą UIImageViews od lewej do prawej. Kod działa w wątku interfejsu użytkownika, aby zapewnić, że nowo widoczne UIImageView mają przypisany świeżo załadowany UIImage. Ładowanie odbywa się na wątku w tle.
Wszystko działa prawie w porządku, z wyjątkiem zacięcia, gdy każdy obraz staje się widoczny. Na początku myślałem, że mój program działający w tle blokuje coś w wątku interfejsu użytkownika. Spędziłem dużo czasu patrząc na to i w końcu zdałem sobie sprawę, że UIImage wykonuje trochę leniwego przetwarzania w wątku interfejsu użytkownika, gdy po raz pierwszy staje się widoczny. To mnie zastanawia, ponieważ mój wątek roboczy ma wyraźny kod do dekompresji danych JPEG.
W każdym razie, na przeczucie, napisałem kod, który w wątku tła zostanie przekształcony w tymczasowy kontekst graficzny i - na pewno - jąkanie zniknęło. UIImage jest teraz wstępnie ładowany w moim wątku roboczym. Jak na razie dobrze.
Problem polega na tym, że moja nowa metoda „wymuszaj leniwy ładunek obrazu” jest zawodna. Powoduje sporadyczny EXC_BAD_ACCESS. Nie mam pojęcia, co robi UIImage za kulisami. Być może dekompresuje dane JPEG. W każdym razie metoda jest:
+ (void)forceLazyLoadOfImage: (UIImage*)image
{
CGImageRef imgRef = image.CGImage;
CGFloat currentWidth = CGImageGetWidth(imgRef);
CGFloat currentHeight = CGImageGetHeight(imgRef);
CGRect bounds = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
CGAffineTransform transform = CGAffineTransformIdentity;
CGFloat scaleRatioX = bounds.size.width / currentWidth;
CGFloat scaleRatioY = bounds.size.height / currentHeight;
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM(context, scaleRatioX, -scaleRatioY);
CGContextTranslateCTM(context, 0, -currentHeight);
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, CGRectMake(0, 0, currentWidth, currentHeight), imgRef);
UIGraphicsEndImageContext();
}
A EXC_BAD_ACCESS dzieje się na linii CGContextDrawImage. PYTANIE 1: Czy mogę to zrobić w wątku innym niż wątek interfejsu użytkownika? PYTANIE 2: Co to jest właściwie UIImage? PYTANIE 3: Jaki jest oficjalny sposób rozwiązania tego problemu?
Dzięki za przeczytanie tego wszystkiego, każda rada byłaby bardzo mile widziana!