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

0
Georges Oates Larsen 7 marzec 2012, 10:18

2 odpowiedzi

Najlepsza odpowiedź

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";
});
1
omz 7 marzec 2012, 10:31

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";
    }
0
Eugene 7 marzec 2012, 10:37