2016-03-28 13 views
0

"Ne yapmam gerekeni yaz" ın ne zaman yapıldığını ve ne tür bir iş üzerinde ne tür çalışmalar yaptığım konusunda spesifik olmadığımı anlamaya çalışıyorum.NSURLSessionDataTask tamamlama blokları ana iş parçacığı üzerinde mi çağrılıyor?

Anladığım kadarıyla, UI'yi yalnızca ana iş parçacığımda güncelleştirmeliyim. Bunun böyle bir şey yapmanın iyi olmadığı anlamına mı geliyor? Bunu bir GDC çağrısına koymalı mıyım?

[sessionManager dataTaskWithRequest:aRequest completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { 

    someUILabel.text = @"Hello!"; // Updating my UI 
    [someTableView reloadData]; // Ask a table view to reload data 

}]; 

Bu, UI parçası için geçerlidir. Şimdi, benim sınıfımda bir yerde bir NSMutableArray olduğunu varsayalım. Bu diziye örneğin UIButton'a dokunarak nesneleri ekliyor veya kaldırıyordum. Sonra tekrar bir NSURLSessionDataTask böylece gibi bazı veri almak ve benim NSMutableArray içine yüklemek için bir yere bir sunucuya gidiş vardır:

[sessionManager dataTaskWithRequest:aRequest completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { 

    myMutableArray = [[responseObject objectForKey:@"results"] mutableCopy]; 

}]; 

Bu UI operasyonu değil. Bu, tamamlama bloğu çalışırken bir nesnenin eklenmesi (yani [myMutableArray insertObject:someObj atIndex:4];) arasındaki bir yarış koşulunda kilitlenmesini önlemek için bir GDC çağrısına sarılmalı mı, yoksa bunlar birbirine çatışmayacak şekilde tasarlanmış mı?

Eldeki soruya odaklanmak için tüm hata işlemlerini dışarıda bıraktım.

cevap

3

TLDR: Tamamlama işleyicinizin içinde dispatch_async(dispatch_get_main_queue()...'u aramak için hiçbir şey yapmanıza gerek yok, sadece bunu yapın.

Uzun Cevap:

Konuyu en belgelerine bakalım?

completionHandler Yükleme isteği tamamlandığında çağrılacak tamamlama işleyicisi. Bu işleyici, temsilci sırasına göre yürütülür.

Temsilci sırası, NSURLSession'ı sessionWithConfiguration:delegate:delegateQueue: ile oluşturduğunuz sırada girdiğiniz sıradır. Bu NSURLSession yöntemini nasıl oluşturduysanız, numaralı öneriyi tamamlama işleyicisinin çağrıldığı sıraya ilişkin varsayımı yapmamanızı öneririm. Bu parametre olarak [NSOperationQueue mainQueue]'u geçmediyseniz, arka plan sırasızsınız ve iş parçacığı güvenli olmayan bir şey yapmadan önce ana sıraya geçmeniz gerekir.

Şimdi soru şudur: evreli UI güncelleştirmek ve tablo görünümünde konuşmak

  • mi? Hayır, bu şeyleri sadece ana kuyrukta yapmalısınız.

  • myMutableArray ayarlamak için iplik güvenli midir? Hayır, daha sonra iki iş parçacığı (genellikle bu özellikle konuştuğunuz ana sıra ve bu kuyruğu, ne olursa olsun) arasında bir özelliği paylaştığınız için.

+0

"Öyleyse yap": Tabi ki yapabilirdim, ama aslında gerekli olup olmadığına, hatta anlamlandırılmayacağına emin olmadan her yere gönderim yapardım. Bunun eldeki probleme bir çözüm olduğunun farkındayım, ama sorunu anlamaya çalışıyorum. Ama açıkladığın için teşekkürler.Kendimi daha fazla eğitmek için belgelere baktım. Ancak AFNetworking kullanıyorum ve varsayılan olarak bu, aksi belirtilmedikçe, ana iş parçacığı üzerinde completeionBlocks çalışır gibi görünüyor, bu yüzden bir şey yapmanıza gerek yok sanırım. Bunu biliyor olamazsın. – nickdnk

+0

Elbette, yeterince adil. Umarım aramızdaki iki hususu, yani hangi iş parçacığı olduğunu ve bu iş parçacığı için güvenli bir hamle yaptık. – matt

+0

Evet, teşekkürler. Sadece bir şeyi yanlış anlamadığımdan emin olmak için: AFNetworking'in ana iş parçacığı üzerinde tamamlanmasının altından çalıştığını farz edersek, o zaman * bu bloğa ait özniteliğe (myMutableArray) doğrudan erişim için iyidir, çünkü aynı iş parçacığı tarafından yanıtlanır. diziyi aynı anda değiştirecek varsayımsal UIButton olayı? Diğer bir deyişle; aynı zamanda olmazdı. – nickdnk

İlgili konular