Làm thế nào để tôi sử dụng một NSTimer
? Bất cứ ai có thể cho tôi hướng dẫn từng bước?
Làm thế nào để tôi sử dụng một NSTimer
? Bất cứ ai có thể cho tôi hướng dẫn từng bước?
Câu trả lời:
Đầu tiên tôi muốn thu hút sự chú ý của bạn vào tài liệu Cacao / CF (luôn là một cổng gọi đầu tiên tuyệt vời). Các tài liệu của Apple có một phần ở đầu mỗi bài viết tham khảo có tên là "Hướng dẫn đồng hành", trong đó liệt kê các hướng dẫn cho chủ đề đang được ghi lại (nếu có). Ví dụ, với NSTimer
, tài liệu liệt kê hai hướng dẫn đồng hành:
Đối với tình huống của bạn, bài viết Chủ đề lập trình hẹn giờ có thể là hữu ích nhất, trong khi các chủ đề luồng có liên quan nhưng không liên quan trực tiếp nhất đến lớp được ghi lại. Nếu bạn xem bài viết Chủ đề lập trình hẹn giờ, nó được chia thành hai phần:
Đối với các bài viết có định dạng này, thường có một cái nhìn tổng quan về lớp và nó được sử dụng để làm gì, và sau đó là một số mã mẫu về cách sử dụng nó, trong trường hợp này là trong phần "Sử dụng bộ đếm thời gian". Có các phần về "Tạo và lên lịch cho bộ định thời", "Dừng bộ hẹn giờ" và "Quản lý bộ nhớ". Từ bài viết, việc tạo một bộ đếm thời gian không lặp lại theo lịch trình có thể được thực hiện như sau:
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(targetMethod:)
userInfo:nil
repeats:NO];
Điều này sẽ tạo ra một bộ đếm thời gian đó bị sa thải sau 2,0 giây và gọi targetMethod:
về self
với một đối số, mà là một con trỏ đến các NSTimer
ví dụ.
Nếu sau đó bạn muốn xem chi tiết hơn về phương pháp, bạn có thể tham khảo lại các tài liệu để biết thêm thông tin, nhưng cũng có giải thích xung quanh mã.
Nếu bạn muốn dừng bộ hẹn giờ lặp lại, (hoặc dừng bộ hẹn giờ không lặp lại trước khi nó kích hoạt) thì bạn cần giữ một con trỏ tới NSTimer
thể hiện đã được tạo; thường thì đây sẽ là một biến đối tượng để bạn có thể tham chiếu đến nó trong một phương thức khác. Sau đó bạn có thể gọi invalidate
vào NSTimer
Ví dụ:
[myTimer invalidate];
myTimer = nil;
Đó cũng là một cách thực hành tốt để nil
loại bỏ biến đối tượng (ví dụ: nếu phương thức của bạn làm mất hiệu lực bộ định thời gian được gọi nhiều lần và biến đối tượng không được đặt thành nil
và đối tượng NSTimer
đã được xử lý, nó sẽ đưa ra một ngoại lệ).
Cũng lưu ý điểm về Quản lý bộ nhớ ở cuối bài viết:
Vì vòng lặp chạy duy trì bộ hẹn giờ, từ góc độ quản lý bộ nhớ , thông thường không cần phải giữ tham chiếu đến bộ hẹn giờ sau khi bạn lên lịch . Vì bộ định thời được truyền dưới dạng đối số khi bạn chỉ định phương thức của nó làm bộ chọn, nên bạn có thể làm mất hiệu lực bộ định thời lặp lại khi thích hợp trong phương thức đó . Tuy nhiên, trong nhiều tình huống, bạn cũng muốn tùy chọn vô hiệu hóa bộ đếm thời gian có lẽ ngay cả trước khi nó bắt đầu. Trong trường hợp này, bạn cần phải giữ một tham chiếu đến bộ đếm thời gian, để bạn có thể gửi cho nó một tin nhắn không hợp lệ bất cứ khi nào thích hợp. Nếu bạn tạo một bộ đếm thời gian không được lên lịch (xem bộ đếm thời gian không theo lịch sử), thì bạn phải duy trì một tham chiếu mạnh đến bộ định thời gian (trong môi trường được tính tham chiếu, bạn giữ lại nó) để nó không bị hủy trước khi sử dụng.
YES
cho repeats:
khi bạn gọi scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
. Nếu bạn làm như vậy thì hãy đảm bảo giữ một tham chiếu đến NSTimer
thể hiện (nó được trả về bởi phương thức) và làm theo điểm trên Quản lý bộ nhớ như tôi đã trình bày chi tiết ở trên.
target
và selector
. Ví dụ: nếu mục tiêu của bạn là self
và bộ chọn là timerMethod:
, phương thức được gọi khi bộ định thời kích hoạt được timerMethod:
xác định trên self
. Sau đó, bạn có thể đặt bất kỳ mã nào bạn muốn trong phương thức đó và phương thức sẽ được gọi bất cứ khi nào bộ định thời kích hoạt. Lưu ý rằng phương thức được gọi khi bộ định thời kích hoạt (mà bạn truyền vào là selector:
) chỉ có thể nhận một đối số (mà khi được gọi là một con trỏ tới NSTimer
thể hiện).
self
"
có một vài cách sử dụng bộ đếm thời gian:
1) hẹn giờ theo lịch trình & sử dụng bộ chọn
NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:@selector(onTick:)
userInfo: nil repeats:NO];
Là một lưu ý phụ, thay vì sử dụng bộ hẹn giờ không lặp lại và gọi bộ chọn sau một khoảng thời gian xác định, bạn có thể sử dụng một câu lệnh đơn giản như sau:
[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];
điều này sẽ có tác dụng tương tự như mã mẫu ở trên; nhưng nếu bạn muốn gọi bộ chọn mỗi lần thứ n, bạn sử dụng bộ hẹn giờ với số lần lặp lại: CÓ;
2) hẹn giờ tự lên lịch
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) hẹn giờ đột xuất và sử dụng lời mời
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];
và sau đó, bạn bắt đầu hẹn giờ bằng tay bất cứ khi nào bạn cần như thế này:
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];
Và như một lưu ý, phương thức onTick: như thế này:
-(void)onTick:(NSTimer *)timer {
//do smth
}
Một cái gì đó như thế này:
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
không bao giờ được giải quyết.
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];
-(void)timerCalled
{
NSLog(@"Timer Called");
// Your Code
}
Các câu trả lời bị thiếu một thời gian cụ thể của bộ đếm thời gian trong ngày ở đây là vào giờ tiếp theo:
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];
Tất nhiên, thay thế "doRefresh" bằng phương thức mong muốn của lớp bạn
cố gắng tạo đối tượng lịch một lần và làm cho allUnits trở thành tĩnh cho hiệu quả.
thêm một thành phần giờ hoạt động tốt, không cần kiểm tra nửa đêm ( liên kết )