2011-02-03 15 views
6

Moja klasa modeli musi pobrać pewne dane z Internetu. Postanowiłem więc uruchomić go w innym wątku, aby ui nie zamarzł. Więc kiedy obiekt chce jakieś dane to najpierw pyta model używając metody tego typu:Metoda uruchamiania głównego wątku z innego wątku

- (void)giveMeSomeData:(id)object withLabel:(id)label { 
objectAsking= object; 
theLabel= label; 
NSThread* thread= [[NSThread alloc] initWithTarget:self selector:@selector(getTheDataFromInternet) object:nil]; 
[thread start]; 
} 

- (void)getTheDataFromInternet { 
//getting data... 

theData= [dataFromInternet retain]; //this is the data the object asked for 
[self returnObjectToAsker]; 
} 

- (void)returnObjectToAsker { 
[objectAsking receiveData:theData withLabel:theLabel]; 
} 

Ponieważ jestem jeszcze nowicjuszem, możesz mi powiedzieć, czy jest to dobry wzór?

Dzięki!

+1

Nie zapomnij wydać tego, co tworzysz, zgodnie z zasadami zarządzania pamięcią. http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html Z kodu, który pokazałeś, powinieneś posiadać i, jeśli nie działa pod GC, ostatecznie zwolnić zarówno "wątek" jak i " theData ". –

+1

Również brzmi to tak, jak 'getTheDataFromInternet' robi to synchronicznie. Nie rób tego - będziesz blokować swój interfejs użytkownika przez ileś milisekund/sekund/minut/godzin/dni, aby pobrać dane. Nie ma znaczenia jak mały jest on ani jak niesamowite jest twoje własne połączenie internetowe - Twoi użytkownicy zobaczą, że twoja aplikacja blokuje się podczas oczekiwania na dane. Zamiast tego utwórz (i przejąć) połączenie NSURLConnection, aby otrzymywać asynchronicznie: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/ Zgłoś postęp za pomocą (przynajmniej) NSProgressIndicator. –

+0

Oczywiście zdecydowałem się nie pisać tych linii dla zachowania przejrzystości;) –

Odpowiedz

12

Twoje ustawienia są prawie poprawne. Nigdy nie chcesz zainicjować żadnego połączenia sieciowego w głównym wątku.

W obecnej postaci, -returnObjectToAsker zostanie wykonany na wątku tła.

Prawdopodobnie byłbyś zainteresowany -[NSObject performSelectorOnMainThread:withObject:waitUntilDone:].

Lub jeśli chciał coś z Grand Central Dispatch (iOS 4+, Mac OS X 10.6+), można zrobić:

#import <dispatch/dispatch.h> 

- (void)giveMeSomeData:(id)object withLabel:(id)label { 
    dispatch_async(dispatch_get_global_queue(0,0), ^{ 
     //this runs on a background thread 
     //get data from the internet 
     dataFromTheInternet = ...; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
     [object receiveData:dataFromTheInternet withLabel:label]; 
     //this runs on the main thread. Use theData 
     }); 
    }); 
} 

Ponieważ bloki uchwycić ich środowisko, nie będzie nawet mieć aby zaoszczędzić object i label na ivars. :)

+0

Dziękuję za szybką odpowiedź :) Co wolisz, GCD lub używanie NSThread? –

+1

@Forchita, jeśli mogę uciec tylko z obsługą iOS 4 lub OS 10.6, to wolę używać GCD, ponieważ mogę zachować całą logikę w jednej metodzie. –

Powiązane problemy