AFNetworking (AFXMLRequestOperation) Main Thread’i Engelliyor
Bir önceki yazıda bahsettiğim uygulamayı neredeyse bitirdim fakat bir problem nedeniyle AppStore’a gönderemedim. Uygulamada AFNetworking’in AFXMLRequestOperation classını kullanarak RSS datasını çekip, gelen xml’i parse edip ilgili mutable (sonradan öğe eklenebilen) dizilere doldurmayı ve bir table’ı bu dizideki elemanlarla oluşturmayı hedefliyordum.
İlgili viewController classıma xml parsing delegate metodlarını yazabilmek için <NSXMLParserDelegate> ibaresini ekledim ve gereken metodları yazdım. İşlem gayet düzgün çalıştı fakat veriler parse edildikten neredeyse 2-3 saniye sonra table güncelleniyordu.Halbuki [self.tableView reloadData] fonksiyonunu parsing işleminin bitiminde çalışan
- (void)parserDidEndDocument:(NSXMLParser *)parser
fonksiyonuna eklemiştim.
Debug yapınca reloadData’nın sırası geldiği halde çalışmadığını, AFNetworking’in parse işleminden sonra başka rutinlerinin icra edildiğini, 1-2 saniye sonra reloadData’ya sıra geldiğini farkettim.
Google’da araştırınca sorunun kaynağını buldum. AFNetworking operasyonu sürerken uygulamamızın ana thread’i (bellekte yer teşkil eden ana prosess) bloke ediyormuş. Sorunun ne olduğunu düzgün ifade edince çözümü bulmak da kolaylaştı. Tabi gerçek çözüme ulaşana kadar 8-10 saçma sapan deney yapmadım değil. Asıl mesele sorunu tam anlamakmış. O zaman çözüm de kolayca bulundu.
Yukarıda bahsettiğim fonksiyonda (parserDidEndDocument) yer verdiğim [self.tableView reloadData] rutinini şu şekilde yazmak gerekiyormuş;
if ([NSThread isMainThread]) { [self.tableView reloadData]; } else { [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; }
Bu ifadeyi ilk kez kullandım. Demek ki iç thread’lerden birindeysek ve ana thread’de bir iş yaptırmak istiyorsak performSelectorOnMainThread diye bir fonksiyon imdadımıza yetişiyormuş. Öğrenmiş olduk.