ฉันจะใช้อย่างไรNSTimer
? ทุกคนสามารถให้คำแนะนำทีละขั้นตอนกับฉันได้ไหม
ฉันจะใช้อย่างไรNSTimer
? ทุกคนสามารถให้คำแนะนำทีละขั้นตอนกับฉันได้ไหม
คำตอบ:
ก่อนอื่นฉันต้องการดึงความสนใจของคุณไปที่เอกสาร 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" ด้วยวิธีการที่ต้องการในชั้นเรียนของคุณ
พยายามสร้างวัตถุปฏิทินหนึ่งครั้งและทำให้หน่วยทั้งหมดเป็นแบบสแตติกเพื่อประสิทธิภาพ
การเพิ่มคอมโพเนนต์หนึ่งชั่วโมงทำงานได้ดีไม่จำเป็นต้องทดสอบเที่ยงคืน ( ลิงก์ )