Ios / objective-c: возможен ли nstimer без обработчика в objective-c?

Я пытаюсь перевести некоторый 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 или как я могу использовать время для обновления одного слова за раз? Спасибо заранее за любые предложения.

Фактически он использует scheduledTimerWithTimeInterval:repeats:block: (iOS10 +), у которого есть блок, переведенный на Swift как Closure. Вы действительно не хотите использовать тот же метод и использовать @selector()?

Larme 13.09.2018 18:21

Вы должны создать свойства, которые могут быть извлечены (либо @property вашего объекта, содержащего его), либо, как вы сказали, используйте userInfo с wordArray и wordIndex и т. д. Это многословно.

Larme 13.09.2018 18:35
2
2
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Другие вопросы по теме