IOS/Objective-C:objective-C 中可能没有处理程序的 NSTimer?
IOS/Objective-C: NSTimer without handler possible in objective-C?
我正在尝试将一些 Swift 用于在 Timer 中用于为新闻行情效果键入单词的 Swift 翻译成 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 做些什么吗?或者我如何利用时间一次更新一个词?提前感谢您的任何建议。
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]
});
}
}
不需要定时器。
我正在尝试将一些 Swift 用于在 Timer 中用于为新闻行情效果键入单词的 Swift 翻译成 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 做些什么吗?或者我如何利用时间一次更新一个词?提前感谢您的任何建议。
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]
});
}
}
不需要定时器。