Yanıtlar:
Öncelikle, dikkatinizi Cocoa / CF belgelerine çekmek istiyorum (her zaman harika bir ilk bağlantı noktasıdır). Apple dokümanlarında, her bir referans makalenin üstünde, "Tamamlayıcı Kılavuzlar" adında bir bölüm bulunur ve bu bölüm belgelenen konunun (varsa) kılavuzlarını listeler. Örneğin, birlikte NSTimer
, dokümantasyon listeleri İki tamamlayıcı kılavuzları:
Durumunuz için, Zamanlayıcı Programlama Konuları makalesi muhtemelen en yararlı olanıdır, ancak iş parçacığı konuları ilişkilidir ancak belgelenen sınıfla en doğrudan ilişkili değildir. Zamanlayıcı Programlama Konuları makalesine göz atarsanız, makale iki bölüme ayrılır:
Bu biçimi almak eşyalar için, ilgili sınıfın ve ne için kullanılır ve daha sonra bazı örnek kod bir bakış var genelde nasıl "kullanma Zamanlayıcılar" bölümünde bu durumda, kullanmak. "Zamanlayıcı Oluşturma ve Zamanlama", "Zamanlayıcıyı Durdurma" ve "Bellek Yönetimi" bölümleri vardır. Makaleden, planlanmış, tekrar etmeyen bir zamanlayıcı oluşturmak şu şekilde yapılabilir:
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(targetMethod:)
userInfo:nil
repeats:NO];
Bu 2,0 saniye sonra ateş ve çağrıları bir zamanlayıcı yaratacak targetMethod:
üzerinde self
bir göstericidir tek argümanı ile NSTimer
örneğin.
Daha sonra yönteme daha ayrıntılı bir şekilde bakmak isterseniz, daha fazla bilgi için dokümanlara geri dönebilirsiniz, ancak kodun etrafında da bir açıklama var.
Tekrar eden bir zamanlayıcıyı durdurmak (veya tekrar etmeyen bir zamanlayıcıyı tetiklemeden önce durdurmak) istiyorsanız NSTimer
, oluşturulan örneğe bir işaretçi tutmanız gerekir ; genellikle başka bir yöntemde başvurabilmeniz için bunun bir örnek değişkeni olması gerekir. Daha sonra arayabilir invalidate
üzerinde NSTimer
Mesela:
[myTimer invalidate];
myTimer = nil;
nil
Örnek değişkenini dışarıda bırakmak da iyi bir uygulamadır (örneğin, zamanlayıcıyı geçersiz kılan yönteminiz birden fazla çağrılırsa ve örnek değişkeni ayarlanmamışsa nil
ve NSTimer
örnek yeniden yerleştirilmişse, bir istisna atar).
Ayrıca makalenin altındaki Bellek Yönetimi konusuna dikkat edin:
Çalışma döngüsü zamanlayıcıyı koruduğundan, bellek yönetimi açısından, zamanlayıcıyı planladıktan sonra genellikle bir zamanlayıcıya başvurmaya gerek yoktur . Zamanlayıcı, yöntemini seçici olarak belirttiğinizde bağımsız değişken olarak iletildiğinden, uygun olduğunda bu yöntemde yinelenen bir zamanlayıcıyı geçersiz kılabilirsiniz . Bununla birlikte, birçok durumda, belki de başlamadan önce zamanlayıcıyı geçersiz kılma seçeneğini de istersiniz. Bu durumda, zamanlayıcıya bir referans tutmanız gerekir, böylece uygun olduğunda ona geçersiz bir mesaj gönderebilirsiniz. Planlanmamış bir zamanlayıcı oluşturursanız (bkz. “Planlanmamış Zamanlayıcılar”), kullanmadan önce zamanlayıcıya yerleştirilmemesi için zamanlayıcıya (referans olarak sayılan bir ortamda tuttuğunuzdan) güçlü bir referans sağlamanız gerekir.
YES
için repeats:
Aradığınızda scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
. Bunu yaparsanız, NSTimer
örneğe başvurduğunuzdan emin olun (yöntem tarafından döndürülür) ve yukarıda ayrıntılı olarak açıkladığım gibi Bellek Yönetimi noktasını izleyin.
target
ve selector
. Hedef ise Örneğin, self
ve seçicidir timerMethod:
zamanlayıcı yangınları olduğunda, yöntemi denir timerMethod:
üzerinde tanımlı self
. Daha sonra bu yöntemde istediğiniz kodu koyabilirsiniz ve zamanlayıcı her tetiklendiğinde yöntem çağrılır. Zamanlayıcı tetiklendiğinde (olarak kabul ettiğiniz) çağrılan yöntemin selector:
yalnızca bir argüman alabileceğini unutmayın (çağrıldığında NSTimer
örneğe bir işaretçi ).
self
" anlamına geliyordu
bir zamanlayıcı kullanmanın birkaç yolu vardır:
1) programlı zamanlayıcı ve seçici kullanarak
NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:@selector(onTick:)
userInfo: nil repeats:NO];
Yan not olarak, belirtilen aralıktan sonra tekrarlayıcı olmayan ve seçiciyi çağıran bir zamanlayıcı kullanmak yerine, aşağıdaki gibi basit bir ifade kullanabilirsiniz:
[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];
bu yukarıdaki örnek kodla aynı etkiye sahip olacaktır; ancak seçiciyi her nci seferde çağırmak istiyorsanız, zamanlayıcıyı tekrarlarla kullanırsınız: YES;
2) kendinden programlı zamanlayıcı
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) programlanmamış zamanlayıcı ve çağrı kullanma
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];
ve bundan sonra, böyle bir şeye ihtiyacınız olduğunda zamanlayıcıyı manuel olarak başlatırsınız:
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];
Ve bir not olarak, onTick: yöntemi şöyle görünür:
-(void)onTick:(NSTimer *)timer {
//do smth
}
Bunun gibi bir şey:
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
asla yeniden konumlandırılmaz .
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];
-(void)timerCalled
{
NSLog(@"Timer Called");
// Your Code
}
Cevaplar günün belirli bir zamanlayıcısını kaçırıyor, burada bir sonraki saatte:
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];
Tabii ki, "doRefresh" yerine sınıfınızın istediğiniz yöntemini kullanın
takvim nesnesini bir kez oluşturmaya çalışın ve allUnits'i verimlilik için statik hale getirin.
bir saatlik bileşen eklemek iyi çalışıyor, gece yarısı testine gerek yok ( bağlantı )