IOS / Objective-C: NSTimer без обработчика возможен в Objective-C? - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь перевести некоторый Swift, который использует Timer для ввода слов для эффекта новостной ленты, в Objective -C.

В Swift вы можете сделать что-то вроде:

    func type(string: String) {
        var wordArray  = ["Sox Win", "Verlander To Start", "Race Tightens"] // an array of strings
        var wordIndex = 0
        Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { (timer) in
            self.textview.text.append(wordsArray[wordIndex])
            wordIndex += 1
            if wordIndex == wordArray.count {
                timer.invalidate()
            }
        }
    }
}

Однако в Objective-C вы обычно видите:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 1.0
                      target: self
                      selector:@selector(update:)
                      userInfo: nil repeats:YES];
-(void) update:(NSTimer*)timer
{
int i=0;i<4;i++ {
NSLog(@"another second");
}
timer.invalidate;
timer = nil;
}

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

- (void)updateView:(NSTimer *)timer
{
NSArray*items =@[@"item1", @"item2", @"item3", @"item4", @"item5"];
 for(int i=0;i<[items count];i++){
    self.textView.text = [self.textView.text stringByAppendingString:items[i]];
    if (i == [items count]) {
        [self.timer invalidate];
        self.timer = nil;
    }
    }
}

Должен ли я что-то делать с userInfo или как использовать время для обновления одного слова за раз? Заранее спасибо за любые предложения.

1 Ответ

0 голосов
/ 13 сентября 2018

Objective-C поддерживает один и тот же блочный метод NSTimer.Перевод вашего метода Swift:

- (void)type:(NSString *)string {
    NSArray *wordArray = @[ @"Sox Win", @"Verlander To Start", @"Race Tightens" ];
    __block NSInteger wordIndex = 0;
    [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        // append wordsArray[wordIndex]
        wordIndex += 1;
        if (wordIndex == wordArray.count) {
            [timer invalidate];
        }
    }];
}

Если по какой-то причине вы действительно хотите использовать таймер на основе селектора, вам нужно будет сохранить массив и индекс в переменных экземпляра.Но в этом и заключается смысл использования этого блочного решения - вы избегаете всей этой дополнительной работы и дополнительного метода (для селектора).

Другой подход заключается в использовании dispatch_after:

- (void)type:(NSString *)string {
    NSArray *wordArray = @[ @"Sox Win", @"Verlander To Start", @"Race Tightens" ];

    for (NSInteger i = 0; i < wordArray.count; i++) {
        dispatch_after(i + 0.1, dispatch_get_main_queue(), ^{
            // append wordsArray[i]
        });
    }
}

Таймер не требуется.

...