iOS 의 NSTimer 타이머 초기 사용 분석
- (void)viewDidLoad {
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(actionTimer:) userInfo:nil repeats:YES];
}
- (void)actionTimer:(NSTimer *)timer
{
}
NSTimer 는 기본적으로 default mode 에서 실 행 됩 니 다.default mode 는 거의 모든 입력 원(NSConnection 제외)NSDefaultRunLoopMode 모드 를 포함 합 니 다.actionTimer 방법 은 1s 마다 호출 됩 니 다.NSTimer 는 사용 하기에 매우 간단 하지 않 습 니까?NSTimer 의 초기 응용 프로그램 입 니 다.
메 인 화면 이 미 끄 러 졌 을 때 NSTimer 가 효력 을 잃 었 습 니 다.
메 인 화면 이 미 끄 러 지 는 것 은 무슨 뜻 입 니까?즉,메 인 화면 에 UITableView 나 UIScrollView 가 있 고 UITableView 나 UIScrollView 를 미 끄 러 뜨 린 다.이 럴 때 NSTimer 가 효력 을 잃 었 습 니 다.
UITableView 가 있 는 UIViewController 에서 타 이 머 를 시작 하고 1s 마다 1 을 추가 하 며 이 숫자 를 UILabel 에 표시 합 니 다.
- (void)viewDidLoad {
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(actionTimer:) userInfo:nil repeats:YES];
}
- (void)actionTimer:(NSTimer *)timer
{
self.number++;
self.label.text = [NSString stringWithFormat:@"%d",self.number];
NSLog(@"%d",self.number);
}
UITableView 와 UILabel 의 생 성에 대해 서 는 생략 하 겠 습 니 다.자세 한 코드 는 여 기 를 클릭 하여 다운로드 할 수 있 습 니 다.iOS StrongDemo,iOS StrongDemo 는 제 가 계속 업데이트 하 겠 습 니 다.여러분 은 github 에 star 를 올 려 주세요.이렇게 하면 사용자 가 UITableView 가 UITracking RunLoopMode 에 있 을 때 NSTimer 는 효력 을 잃 고 fire 가 될 수 없습니다.self.label 의 숫자 도 업데이트 할 수 없습니다.
NSTimer 의 run loop 수정
해결 방법 은 이 를 UITracking RunLoopMode 모드 나 NSRunLoopCommonModes 모드 에 추가 하 는 것 이다.
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
혹은
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
NSRunLoop CommonModes:하나의 모드 집합 입 니 다.하나의 이벤트 가 이 모드 로 집합 되 었 을 때 집합 안의 모든 모드 에 연결 되 는 것 과 같 습 니 다.fire
우 리 는 먼저 NSTimer 로 간단 한 타 이 머 를 만들어 서 5 초 마다 콘 솔 에서 Fire 를 출력 합 니 다.비교적 당연 하 다 고 생각 하 는 방법 은 이렇다.
@interface DetailViewController ()
@property (nonatomic, weak) NSTimer *timer;
@end
@implementation DetailViewController
- (IBAction)fireButtonPressed:(id)sender {
_timer = [NSTimer scheduledTimerWithTimeInterval:3.0f
target:self
selector:@selector(timerFire:)
userInfo:nil
repeats:YES];
[_timer fire];
}
-(void)timerFire:(id)userinfo {
NSLog(@"Fire");
}
@end
실행 한 후에 콘 솔 에서 3 초 에 한 번 씩 Fire 를 출력 하 는 것 이 확실 합 니 다.그러나 우리 가 이 인터페이스 에서 다른 인터페이스 로 넘 어 갔 을 때 콘 솔 은 아직도 Fire 를 끊임없이 출력 하고 있 습 니 다.타 이 머 는 멈 추 지 않 은 것 같다.invalidate
멈 추 지 않 았 으 니 데모 뷰 컨트롤 러 의 dealloc 에 invalidate 방법 을 추가 합 니 다.
-(void)dealloc {
[_timer invalidate];
NSLog(@"%@ dealloc", NSStringFromClass([self class]));
}
다시 실행 해도 멈 추 지 않 았 습 니 다.이 유 는 Timer 가 Runloop 에 추 가 될 때 Runloop 에 의 해 강하 게 인용 되 기 때 문 입 니 다.Note in particular that run loops maintain strong references to their timers, so you don't have to maintain your own strong reference to a timer after you have added it to a run loop.
그리고 Timer 는 Target 에 대한 강 한 인용(즉 self)이 있 습 니 다.
Target is the object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to target until it (the timer) is invalidated.
NSTimer 가 self 를 강하 게 인용 해 self 가 풀 려 나 지 않 아 self 의 dealloc 에 들 어가 지 못 한 다 는 것 이다.
그렇다면 invalidate 단 추 를 추가 할 수 있 습 니 다.
- (IBAction)invalidateButtonPressed:(id)sender {
[_timer invalidate];
}
이렇게 하면 돼.SOF 에서 어떤 분 이 invalidate 이후 에 실행 해 야 된다 고...timer=nil,이 유 를 이해 하지 못 했 습 니 다.이 유 를 알 고 있다 면 알려 주세요.)invalidate 방법의 문서 에 다음 과 같은 말 이 있 습 니 다.
You must send this message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.
NSTimer 가 어느 스 레 드 에서 만 들 면 어느 스 레 드 에서 멈 춰 야 합 니까?그렇지 않 으 면 자원 이 올 바 르 게 방출 되 지 않 습 니 다.보아하니 각종 구덩이 가 아직 적지 않 은 것 같다.
dealloc
그러면 문제 가 생 겼 습 니 다.만약 에 제 가 이 NSTimer 를 계속 출력 시 키 려 고 했 는데 DemoViewController 가 소각 되 어야 멈 추 었 습 니 다.제 가 어떻게 멈 추 게 해 야 합 니까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
View의 레이아웃 방법을 AutoLayout에서 따뜻한 손 계산으로 하면 성능이 9.26배로 된 이야기이 기사는 의 15 일째 기사입니다. 어제는 에서 이었습니다. 손 계산을 권하는 의도는 없고, 특수한 상황하에서 계측한 내용입니다 화면 높이의 10 배 정도의 contentView가있는 UIScrollView 레이아...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.