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생성 된 인스턴스에 대한 포인터를 유지해야합니다 . 종종 이것은 다른 방법으로 참조 할 수 있도록 인스턴스 변수 여야합니다. 그런 다음 호출 할 수 있습니다 invalidate온 NSTimer예 :

[myTimer invalidate];
myTimer = nil;

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

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

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


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.