Sonntag, Juni 7, 2020

Obj-C -> Inkrementieren einer Zahl (und zeigt Schritte auf einer Kakao-label)

Ich bin neu mit Objective-C, so gibt es wahrscheinlich eine einfache Lösung dafür.

Ich soll eine Zahl hochgezählt, aber in jeder iteration zu zeigen, die Sie auf einem Etikett. (zum Beispiel, es zeigt 1, 2, 3, 4, 5… angezeigt wird abgesehen von einer Menge Zeit).

Habe ich versucht:

#import "testNums.h"

@implementation testNums
- (IBAction)start:(id)sender {
    int i;
    for(i = 0; i < 10; ++i)
    {
        [outputNum setIntValue:i];
        sleep(1);
    }
}
@end

und alle es Taten, war zu warten, für 9 Sekunden (scheinbar eingefroren) und dann angezeigt 9 in das Textfeld ein.

InformationsquelleAutor aaront | 2008-10-26

2 Kommentare

  1. 6

    Ermöglichen die Schlinge um zwischen Nachrichten, verwenden Sie eine NSTimer oder verzögert durchführen. Hier ist das letztere:

    - (IBAction) start:(id)sender {
        [self performSelector:@selector(updateTextFieldWithNumber:) withObject:[NSNumber numberWithInt:0] afterDelay:1.0];
    }
    
    - (void) updateTextFieldWithNumber:(NSNumber *)num {
        int i = [num intValue];
        [outputField setIntValue:i];
        if (i < 10)
            [self performSelector:@selector(updateTextFieldWithNumber:) withObject:[NSNumber numberWithInt:++i] afterDelay:1.0];
    }

    Hier ist eine timer-basierte Lösung. Sie finden es möglicherweise einfacher, zu Folgen. Sie können die text-Feld den Wert aus dem text-Feld:

    @interface TestNums: NSObject
    {
        IBOutlet NSTextField *outputField;
        NSTimer *timer;
        int currentNumber;
    }
    
    @end
    
    @implementation TestNums
    
    - (IBAction) start:(id)sender {
        timer = [[NSTimer scheduledTimerWithTimeInterval:1.0
            target:self
            selector:@selector(updateTextField:)
            userInfo:nil
            repeats:YES] retain];
    
        //Set the field's value immediately to 0
        currentNumber = 0;
        [outputField setIntValue:currentNumber];
    }
    
    - (void) updateTextField:(NSTimer *)timer {
        [outputField setIntValue:++currentNumber];
    }
    
    @end

    Hier ist noch besser (sauberer) timer-basierten Lösung, mit einer Eigenschaft. Sie müssen binden Sie das Textfeld, um die Eigenschaft im Interface Builder (wählen Sie das Feld, drücken Sie ⌘4 wählen Sie das Objekt, und geben Sie currentNumber als Schlüssel zu binden).

    @interface TestNums: NSObject
    {
        //NOTE: No outlet this time.
        NSTimer *timer;
        int currentNumber;
    }
    
    @property int currentNumber;
    
    @end
    
    @implementation TestNums
    
    @synthesize currentNumber;
    
    - (IBAction) start:(id)sender {
        timer = [[NSTimer scheduledTimerWithTimeInterval:1.0
            target:self
            selector:@selector(updateTextField:)
            userInfo:nil
            repeats:YES] retain];
    
        //Set the field's value immediately to 0
        self.currentNumber = 0;
    }
    
    - (void) updateTextField:(NSTimer *)timer {
        self.currentNumber = ++currentNumber;
    }
    
    @end

    Eigentum-basierte Lösung hat mindestens zwei Vorteile:

    1. Ihr Objekt braucht nicht zu wissen über das Textfeld. (Es ist ein Modell-Objekt, getrennt von der view-Objekt, das text-Feld).
    2. Fügen Sie weitere Textfelder erstellen Sie einfach und binden Sie diese in IB. Sie müssen nicht fügen Sie code für die TestNums Klasse.
  2. 4

    Ja, weil das ist, was Sie gesagt haben, es zu tun. Die Grafik wird nicht wirklich aktualisiert, bis der Hauptlauf Schleife ist frei, um Sie anzuzeigen. Benötigen Sie NSTimer oder eine solche Methode, das zu tun, was Sie wollen.

    Eine bessere Frage könnte sein, warum Sie dies tun wollen?

    • Dies war nur ein Beispiel, die war sehr einfach, zu zeigen, was ich so wollte.

Kostenlose Online-Tests