Krótko mówiąc, chciałbym w Objective-C cocoa zaprogramować coś, co działa tak samo, jak następujący pseudokod Java:
public class MainClass
{
public void mainmethod() //Gets called at start of program
{
UILabel label = CreateAButton();
new DaemonClass(label).start();
//Do things without being interrupted by the Daemon class sleeping or lagging
}
}
public class DaemonClass extends Thread
{
public UILabel label;
public DaemonClass(UILabel lbl)
{
setDaemon(true);
label = lbl;
}
public void run()
{
int i = 0;
while(true)
{
i++;
i = i%2;
UILabel.setText("" + i);
Thread.sleep(1000);
}
}
}
Innymi słowy... chciałbym stworzyć wątek demona, który może być tak wolny, jak tylko chce, bez przerywania postępu lub szybkości innych wątków, W TYM głównego.
Próbowałem używać rzeczy takich jak Dispatch Queue
, a także NSThread
.
Używając jednego z nich, próbowałem stworzyć prosty wątek zmieniający etykiety, który przełączałby tekst etykiety z 1 na 0, w nieskończoność. Wydawało mi się, że użytkownik jest stale blokowany na 1 lub 0, losowo wybierany podczas uruchamiania.
W przypadku użycia jednego z nich i próby użycia [NSThread sleepForTimeInterval:1];
, wątek przestałby wykonywać wszystkie razem po wywołaniu sleepForTimeInterval.
Co więcej, po przejrzeniu dokumentów zauważyłem, że pętla uruchamiania nie jest wywoływana, gdy [NSThread sleep...
śpi!
Jeśli jest jakaś pomoc, wywoływałem moje wątki z metody - (void)viewDidLoad;
.
Moje pytanie do Ciebie to:
Jak zapobiec awarii [NSThread sleepForTimeInterval:1];
mojego wątku LUB: Jak uruchomić wątek demona, który wywołuje metodę lub blok kodu (najlepiej blok kodu!)
PS jeśli to robi jakąkolwiek różnicę, dotyczy to iOS
2 odpowiedzi
Przyczyną problemów, które zauważyłeś, jest najprawdopodobniej to, że UIKit nie jest bezpieczny dla wątków, tj. możesz użyć tylko UILabel
z głównego wątku. Najprostszym sposobem na to jest umieszczenie bloku w kolejce głównej (która jest powiązana z głównym wątkiem) za pomocą GCD:
dispatch_async(dispatch_get_main_queue(), ^{
myLabel.text = @"whatever";
});
Przede wszystkim nie możesz zarządzać UIKit w wątkach w tle. Aby ustawić tekst na UILabel, musisz użyć głównego wątku.
Sądząc po rodzaju zadania, które chcesz osiągnąć, powinieneś użyć NTimera. Możesz ustawić przedział czasu, w którym ma być wywoływany, a także zatrzymać i wznowić w dowolnym momencie.
@property (strong, nonatomic) NSTimer *timer; //in your .h file
- (void)startChangingLabelText {
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(checkTime:)
userInfo:nil
repeats:YES];
}
- (void)stopChangingLabelText {
[timer invalidate], self.timer = nil;
}
- (void)checkTime:(NSTimer *)timer {
int rand = arc4random() % 2;
if (rand)
label.text = @"true";
else
label.text = @"false";
}
Podobne pytania
Nowe pytania
objective-c
Tego znacznika należy używać tylko w przypadku pytań dotyczących funkcji Objective-C lub zależnych od kodu w języku. Tagi [cocoa] i [cocoa-touch] powinny być używane, aby zapytać o ramy lub klasy Apple. Użyj powiązanych tagów [ios], [macos], [apple-watch] i [tvos] w przypadku problemów specyficznych dla tych platform.