답변:
먼저 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
인스턴스가 해제되어, 그것은 예외가 발생합니다).
기사 하단의 메모리 관리에 대한 요점도 참고하십시오.
실행 루프는 타이머를 유지하기 때문에 메모리 관리 측면에서 일반적으로 예약 후 타이머에 대한 참조를 유지할 필요가 없습니다 . 메소드를 선택기로 지정할 때 타이머가 인수로 전달되므로 해당 메소드 내에서 적절한 경우 반복 타이머를 무효화 할 수 있습니다 . 그러나 여러 상황에서 타이머를 시작하기 전에도 무효화하는 옵션을 원할 수도 있습니다. 이 경우 타이머에 대한 참조를 유지해야 할 때마다 무효화 메시지를 보낼 수 있습니다.. 예약되지 않은 타이머를 만들면 ( "예약되지 않은 타이머"참조) 타이머를 사용하기 전에 할당 해제되지 않도록 타이머에 대한 강력한 참조를 유지해야합니다 (참조 계산 환경에서는 유지).
YES
합니다 . 그렇다면 인스턴스에 대한 참조를 유지하고 (메소드에서 반환 됨) 위에서 자세히 설명한대로 메모리 관리의 요점을 따르십시오. repeats:
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
NSTimer
target
및로 지정하는 방법에서 selector
. 예를 들어, 타겟이 self
이고 셀렉터가 timerMethod:
인 경우 타이머가 실행될 때 호출되는 메서드는에 timerMethod:
정의되어 있습니다 self
. 그런 다음 해당 메소드에 원하는 코드를 넣을 수 있으며 타이머가 실행될 때마다 메소드가 호출됩니다. 타이머가 selector:
실행될 때 호출되는 메소드 (로 전달됨 )는 하나의 인수 만 사용할 수 있습니다 (호출시 NSTimer
인스턴스에 대한 포인터 임).
self
"
타이머를 사용하는 몇 가지 방법이 있습니다.
1) 예약 된 타이머 및 선택기 사용
NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:@selector(onTick:)
userInfo: nil repeats:NO];
참고로 지정된 간격 후에 반복하지 않고 선택기를 호출하는 타이머를 사용하는 대신 다음과 같은 간단한 명령문을 사용할 수 있습니다.
[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];
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
MyViewController
결코 할당 해제되지 않습니다.
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 )