[objective-c] NSTimer는 어떻게 사용합니까?

어떻게 사용 NSTimer합니까? 누구든지 단계별 지침을 제공 할 수 있습니까?



답변

먼저 Cocoa / CF 문서 (항상 첫 번째 호출 포트)에주의를 기울이고 싶습니다. Apple 문서에는 각 참조 기사 상단에 “동반자 안내서”라는 섹션이 있으며, 여기에는 문서화되는 주제에 대한 안내서가 있습니다 (있는 경우). 예를 들어,와 NSTimer, 문서의 목록이 동반자 가이드 :

스레딩 주제는 관련되어 있지만 문서화되는 클래스와 가장 직접적으로 관련이없는 상황에서는 타이머 프로그래밍 주제 기사가 가장 유용 할 것입니다. 타이머 프로그래밍 주제 기사를 살펴보면 두 부분으로 나뉩니다.

  • 타이머
  • 타이머 사용

이 형식을 사용하는 기사의 경우 클래스 개요와 사용 방법 및 사용 방법대한 샘플 코드 ( 이 경우 “타이머 사용”섹션)가 있습니다. “타이머 생성 및 예약”, “타이머 중지”및 “메모리 관리”에 대한 섹션이 있습니다. 이 기사에서 예약되고 반복되지 않는 타이머를 만드는 것은 다음과 같이 수행 할 수 있습니다.

[NSTimer scheduledTimerWithTimeInterval:2.0
    target:self
    selector:@selector(targetMethod:)
    userInfo:nil
    repeats:NO];

이는 2.0 초 후에 해고를 호출하는 타이머를 만듭니다 targetMethod:self받는 포인터이다 하나 개의 인수와 NSTimer인스턴스를.

그런 다음 메소드를 더 자세히 보려면 ​​문서를 다시 참조하여 자세한 정보를 얻을 수 있지만 코드에 대한 설명도 있습니다.

반복되는 타이머를 중지하려면 (또는 반복하기 전에 반복되지 않는 타이머를 중지하려면) NSTimer생성 된 인스턴스에 대한 포인터를 유지해야합니다 . 종종 이것은 다른 방법으로 참조 할 수 있도록 인스턴스 변수 여야합니다. 그런 다음 호출 할 수 있습니다 invalidateNSTimer예 :

[myTimer invalidate];
myTimer = nil;

또한 좋은 연습의 nil인스턴스 변수 출력 (예를 들어, 만약 타이머가 더 인스턴스 변수가 설정되지 않았으며 여러 번 호출 무효화 당신의 방법 nilNSTimer인스턴스가 해제되어, 그것은 예외가 발생합니다).

기사 하단의 메모리 관리에 대한 요점도 참고하십시오.

실행 루프는 타이머를 유지하기 때문에 메모리 관리 측면에서 일반적으로 예약 후 타이머에 대한 참조를 유지할 필요가 없습니다 . 메소드를 선택기로 지정할 때 타이머가 인수로 전달되므로 해당 메소드 내에서 적절한 경우 반복 타이머를 무효화 할 수 있습니다 . 그러나 여러 상황에서 타이머를 시작하기 전에도 무효화하는 옵션을 원할 수도 있습니다. 이 경우 타이머에 대한 참조를 유지해야 할 때마다 무효화 메시지를 보낼 수 있습니다.. 예약되지 않은 타이머를 만들면 ( “예약되지 않은 타이머”참조) 타이머를 사용하기 전에 할당 해제되지 않도록 타이머에 대한 강력한 참조를 유지해야합니다 (참조 계산 환경에서는 유지).


답변

타이머를 사용하는 몇 가지 방법이 있습니다.

1) 예약 된 타이머 및 선택기 사용

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];
  • 반복을 NO로 설정하면 타이머가 선택기를 실행하기 전에 2 초 동안 기다린 후 중지됩니다.
  • 반복되는 경우 : 예, 타이머가 즉시 시작되고 2 초마다 선택기 호출을 반복합니다.
  • 타이머를 중지하려면 타이머의 -invalidate 메소드를 호출하십시오. [t invalidate];

참고로 지정된 간격 후에 반복하지 않고 선택기를 호출하는 타이머를 사용하는 대신 다음과 같은 간단한 명령문을 사용할 수 있습니다.

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

이것은 위의 샘플 코드와 같은 효과가 있습니다. 그러나 n 번째로 셀렉터를 호출하려면 타이머를 반복해서 사용하십시오. YES;

2) 자체 예약 타이머

NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
NSTimer *t = [[NSTimer alloc] initWithFireDate: d
                              interval: 1
                              target: self
                              selector:@selector(onTick:)
                              userInfo:nil repeats:YES];

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:t forMode: NSDefaultRunLoopMode];
[t release];
  • 그러면 사용자가 지정한 사용자 지정 날짜 (이 경우 1 분 후)에 자체 타이머가 시작되어 1 초마다 반복됩니다.

3) 예약되지 않은 타이머 및 호출 사용

NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(onTick:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:@selector(onTick:)];

NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
                      invocation:inv
                      repeats:YES];

그리고 나서 다음과 같이 필요할 때마다 수동으로 타이머를 시작합니다.

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];

참고로 onTick : 메서드는 다음과 같습니다.

-(void)onTick:(NSTimer *)timer {
   //do smth
}


답변

이 같은:

NSTimer *timer;

    timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
                     target: self
                     selector: @selector(handleTimer:)
                     userInfo: nil
                     repeats: YES];


답변

#import "MyViewController.h"

@interface MyViewController ()

@property (strong, nonatomic) NSTimer *timer;

@end

@implementation MyViewController

double timerInterval = 1.0f;

- (NSTimer *) timer {
    if (!_timer) {
        _timer = [NSTimer timerWithTimeInterval:timerInterval target:self selector:@selector(onTick:) userInfo:nil repeats:YES];
    }
    return _timer;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

-(void)onTick:(NSTimer*)timer
{
    NSLog(@"Tick...");
}

@end


답변

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];

-(void)timerCalled
{
     NSLog(@"Timer Called");
     // Your Code
}


답변

다음 시간의 특정 시간 타이머에 대한 답변이 누락되었습니다.

NSCalendarUnit allUnits = NSCalendarUnitYear   | NSCalendarUnitMonth |
                          NSCalendarUnitDay    | NSCalendarUnitHour  |
                          NSCalendarUnitMinute | NSCalendarUnitSecond;

NSCalendar *calendar = [[ NSCalendar alloc]
                          initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *weekdayComponents = [calendar components: allUnits
                                                  fromDate: [ NSDate date ] ];

[ weekdayComponents setHour: weekdayComponents.hour + 1 ];
[ weekdayComponents setMinute: 0 ];
[ weekdayComponents setSecond: 0 ];

NSDate *nextTime = [ calendar dateFromComponents: weekdayComponents ];

refreshTimer = [[ NSTimer alloc ] initWithFireDate: nextTime
                                          interval: 0.0
                                            target: self
                                          selector: @selector( doRefresh )
                                          userInfo: nil repeats: NO ];

[[NSRunLoop currentRunLoop] addTimer: refreshTimer forMode: NSDefaultRunLoopMode];

물론, 클래스의 원하는 메소드로 “doRefresh”를 대체하십시오.

달력 개체를 한 번 만들고 효율성을 위해 allUnits를 정적으로 만드십시오.

한 시간 분량의 구성 요소를 추가하면 자정 테스트가 필요하지 않습니다 ( link )


답변