NSTimer는 어떻게 사용합니까?


344

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


1
난에 parameterwise 정보를 가지고 pravinmagdum.wordpress.com/2010/12/30/how-to-use-nstimer 거기에 봐 .. 당신을 위해 도움이 될 수 있습니다

답변:


616

먼저 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인스턴스가 해제되어, 그것은 예외가 발생합니다).

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

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


Okk, 질문 하나, 2 초마다 실행될 코드로 무엇을 넣을까요?
lab12

전화하면을 (를) 전달 YES합니다 . 그렇다면 인스턴스에 대한 참조를 유지하고 (메소드에서 반환 됨) 위에서 자세히 설명한대로 메모리 관리의 요점을 따르십시오. repeats:scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:NSTimer
Alex Rozanski

아니요, 2 초마다 시작되는 코드를 어디에 둘까요? 예를 들어, 2 초마다 경고음을 내고 싶다고 가정 해 봅시다. 경고음 소음 코드를 어디에 두어야합니까?
lab12

target및로 지정하는 방법에서 selector. 예를 들어, 타겟이 self이고 셀렉터가 timerMethod:인 경우 타이머가 실행될 때 호출되는 메서드는에 timerMethod:정의되어 있습니다 self. 그런 다음 해당 메소드에 원하는 코드를 넣을 수 있으며 타이머가 실행될 때마다 메소드가 호출됩니다. 타이머가 selector:실행될 때 호출되는 메소드 (로 전달됨 )는 하나의 인수 만 사용할 수 있습니다 (호출시 NSTimer인스턴스에 대한 포인터 임).
Alex Rozanski

죄송합니다. "에 정의 됨 self"
Alex Rozanski

331

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

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
}

그래도 앱의 투명도를 낮추고
싶어서

24
이봐, 오늘이 사람들 .. 처음부터 그것을 지정하지 않았고 우리가 쓸데없는 글을 썼기 때문에 나에게서 투표하십시오!
Woofy

28
당신은 헛된 글을 쓰지 않았습니다. 이것은 좋은 정보입니다!
willc2

방법 2 "자체 예약 타이머"에서 원하는 타이머를 어떻게 중지 할 수 있습니까?
Satyam

1
@Satyamsvv, 당신은 호출하여 타이머를 중지 할 수 있습니다 다른 방법을 말해 : [timer invalidate]; 타이머 = nil;
Kimpoy

59

이 같은:

NSTimer *timer;

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

14
여전히 강해 ... 2014도!
Muruganandham K

5
#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

어떻게 든 그것은 유지주기를 생성하므로 MyViewController결코 할당 해제되지 않습니다.
Darrarski

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

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

이거 어디서 썼어?
Mohit

1
@JigneshB이 답변은 NSTimer를 백그라운드에서 사용하는 것이 아니라 NSTimer를 사용하는 방법에 관한 것입니다.
Mohit

나는 백그라운드 메소드로 작성했다.-(void) applicationDidEnterBackground : (UIApplication *) application {}
Jignesh B

반복 모드 있음
Jignesh B

Apple의 설명서는 콜백 메소드의 서명에 대해 매우 구체적입니다. 네 잘못이야
Nikolai Ruhe 2019

2

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

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 )

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.