Obj-C -> Увеличение числа (и отображение шагов на ярлыке Какао) - PullRequest
3 голосов
/ 26 октября 2008

Я новичок в Objective-C, так что, вероятно, есть простое решение для этого.

Я хочу, чтобы число увеличивалось, но каждая итерация должна отображаться на метке. (например, он показывает 1, 2, 3, 4, 5 ..., отображаемые отдельно по времени).

Я пытался:

#import "testNums.h"

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

и все, что он сделал, это подождал 9 секунд (очевидно, заморожен), а затем отобразил 9 в текстовом поле.

Ответы [ 2 ]

6 голосов
/ 26 октября 2008

Чтобы разрешить запуск цикла между сообщениями, используйте NSTimer или отложенное выполнение. Вот последний:

- (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];
}

Вот одно решение на основе таймера. Вам может быть легче следовать. Вы можете установить значение текстового поля из текстового поля:

@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

Вот еще лучшее (более чистое) решение на основе таймера, использующее свойство. Вам нужно будет привязать текстовое поле к свойству в Интерфейсном Разработчике (выберите поле, нажмите ⌘4, выберите свой объект и введите currentNumber в качестве ключа для привязки).

@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

Решение на основе свойств имеет как минимум два преимущества:

  1. Ваш объект не должен знать о текстовом поле. (Это объект модели, отдельный от объекта представления, являющегося текстовым полем.)
  2. Чтобы добавить больше текстовых полей, вы просто создаете и связываете их в IB. Вам не нужно добавлять код в класс TestNums.
4 голосов
/ 26 октября 2008

Да, потому что это то, что вы сказали ему делать. Графика на самом деле не будет обновляться, пока основной цикл выполнения не будет свободен для их отображения. Вам нужно будет использовать NSTimer или какой-либо другой способ сделать то, что вы хотите.

Лучший вопрос может быть, почему вы хотите это сделать?

...