Bagaimana saya menggunakan NSTimer?

344

Bagaimana cara menggunakan NSTimer? Adakah yang bisa memberi saya petunjuk langkah demi langkah?

lab12
sumber
1
saya mendapatkan info parameterwise di pravinmagdum.wordpress.com/2010/12/30/how-to-use-nstimer telah melihatnya .. semoga bermanfaat bagi Anda

Jawaban:

616

Pertama-tama saya ingin menarik perhatian Anda pada dokumentasi Kakao / CF (yang selalu merupakan tempat panggilan pertama yang bagus). Dokumen Apple memiliki bagian di bagian atas setiap artikel referensi yang disebut "Panduan Pendamping", yang berisi daftar panduan untuk topik yang didokumentasikan (jika ada). Misalnya, dengan NSTimer, dokumentasi mencantumkan dua panduan pendamping:

Untuk situasi Anda, artikel Topik Pemrograman Waktu cenderung menjadi yang paling berguna, sementara topik threading terkait tetapi tidak yang paling langsung terkait dengan kelas yang didokumentasikan. Jika Anda melihat artikel Topik Pemrograman Waktu, artikel ini dibagi menjadi dua bagian:

  • Pengatur waktu
  • Menggunakan pengatur waktu

Untuk artikel yang menggunakan format ini, sering kali terdapat ikhtisar kelas dan untuk apa digunakannya, dan kemudian beberapa contoh kode tentang cara menggunakannya, dalam hal ini di bagian "Menggunakan Pengatur Waktu". Ada bagian pada "Membuat dan Menjadwalkan Timer", "Menghentikan Timer" dan "Manajemen Memori". Dari artikel tersebut, membuat pengatur waktu terjadwal dan tidak berulang dapat dilakukan seperti ini:

[NSTimer scheduledTimerWithTimeInterval:2.0
    target:self
    selector:@selector(targetMethod:)
    userInfo:nil
    repeats:NO];

Ini akan membuat timer yang dipecat setelah 2,0 detik dan panggilan targetMethod:pada selfdengan satu argumen, yang merupakan pointer keNSTimer instance.

Jika Anda ingin melihat lebih detail pada metode ini, Anda dapat merujuk kembali ke dokumen untuk informasi lebih lanjut, tetapi ada penjelasan di sekitar kode juga.

Jika Anda ingin menghentikan timer yang berulang, (atau menghentikan timer yang tidak berulang sebelum menyala) maka Anda perlu menyimpan pointer ke NSTimerinstance yang telah dibuat; sering kali ini harus berupa variabel instan sehingga Anda dapat merujuknya ke metode lain. Anda kemudian dapat memanggil invalidatepada NSTimercontoh:

[myTimer invalidate];
myTimer = nil;

Ini juga praktik yang baik untuk nilmengeluarkan variabel instan (misalnya jika metode Anda yang membatalkan timer disebut lebih dari sekali dan variabel instan belum disetel ke nildan NSTimerinstance telah dibatalkan alokasi, itu akan mengeluarkan pengecualian).

Perhatikan juga poin tentang Manajemen Memori di bagian bawah artikel:

Karena run loop mempertahankan timer, dari perspektif manajemen memori , biasanya tidak perlu menyimpan referensi ke timer setelah Anda menjadwalkannya . Karena timer dilewatkan sebagai argumen ketika Anda menentukan metode sebagai pemilih, Anda dapat membatalkan timer berulang jika sesuai dalam metode itu . Namun, dalam banyak situasi, Anda juga menginginkan opsi untuk membatalkan timer — mungkin bahkan sebelum itu dimulai. Dalam hal ini, Anda perlu menyimpan referensi ke timer, sehingga Anda dapat mengirimkannya pesan yang tidak valid kapan saja sesuai. Jika Anda membuat pengatur waktu yang tidak terjadwal (lihat “Pengatur Waktu Tidak Terjadwal”), maka Anda harus mempertahankan referensi yang kuat untuk pengatur waktu (dalam lingkungan yang dihitung referensi, Anda mempertahankannya) sehingga tidak dibatalkan alokasi sebelum Anda menggunakannya.

Alex Rozanski
sumber
Okk, satu pertanyaan, apa yang akan saya masukkan sebagai kode saya yang akan dieksekusi setiap dua detik?
lab12
Anda akan melewati YESuntuk repeats:saat Anda menelepon scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:. Jika Anda melakukannya maka pastikan untuk menyimpan referensi ke NSTimerinstance (dikembalikan oleh metode) dan ikuti titik pada Manajemen Memori seperti yang saya perincikan di atas.
Alex Rozanski
Tidak, di mana saya akan meletakkan kode saya yang akan dimulai setiap 2 detik? Sebagai contoh, katakanlah saya ingin membuat suara bip setiap 2 detik. di mana saya akan meletakkan kode suara bip ..?
lab12
Dalam metode yang Anda tentukan dengan targetdan selector. Misalnya, jika target Anda adalah selfdan pemilihnya timerMethod:, metode yang dipanggil ketika timer menyala timerMethod:ditentukan pada self. Anda kemudian dapat memasukkan kode apa pun yang Anda inginkan dalam metode itu, dan metode itu akan dipanggil setiap kali timer menyala. Perhatikan bahwa metode yang dipanggil ketika timer menyala (yang Anda lewati sebagai selector:) hanya dapat mengambil satu argumen (yang ketika dipanggil adalah pointer ke NSTimerinstance).
Alex Rozanski
Maaf, berarti "didefinisikan pada self"
Alex Rozanski
331

ada beberapa cara menggunakan timer:

1) penghitung waktu terjadwal & menggunakan pemilih

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];
  • jika Anda mengatur pengulangan ke TIDAK, timer akan menunggu 2 detik sebelum menjalankan pemilih dan setelah itu akan berhenti;
  • jika diulang: YES, timer akan mulai dengan segera dan akan berulang kali memanggil pemilih setiap 2 detik;
  • untuk menghentikan timer, Anda memanggil metode -invalidasi timer: [t invalidate];

Sebagai catatan tambahan, alih-alih menggunakan penghitung waktu yang tidak berulang dan memanggil pemilih setelah interval yang ditentukan, Anda bisa menggunakan pernyataan sederhana seperti ini:

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

ini akan memiliki efek yang sama dengan kode sampel di atas; tetapi jika Anda ingin memanggil pemilih setiap kali, Anda menggunakan timer dengan pengulangan: YES;

2) pengatur waktu terjadwal

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];
  • ini akan membuat penghitung waktu yang akan dimulai dengan sendirinya pada tanggal khusus yang Anda tentukan (dalam hal ini, setelah satu menit), dan mengulangi sendiri setiap satu detik

3) timer tidak terjadwal & menggunakan doa

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];

dan setelah itu, Anda memulai timer secara manual kapan pun Anda perlu seperti ini:

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];



Dan sebagai catatan, metode onTick: terlihat seperti ini:

-(void)onTick:(NSTimer *)timer {
   //do smth
}
Woofy
sumber
Ok, tapi Anda lihat saya ingin menurunkan transparansi app saya, jadi saya tidak tahu bagaimana menerapkan bahwa dengan NSTimer
lab12
24
Astaga, orang-orang ini hari ini .. memberi suara saya karena Anda tidak menyebutkannya sejak awal dan biarkan kami menulis dengan sia-sia!
Woofy
28
Anda tidak menulis dengan sia-sia. Ini info BAIK!
willc2
Dalam metode 2, "timer yang dijadwalkan sendiri", bagaimana saya bisa menghentikan timer ketika saya mau?
Satyam
1
@ Satyamsvv, Anda dapat menghentikan timer dengan memohon, katakan metode lain memiliki: [timer tidak valid]; timer = nil;
Kimpoy
59

Sesuatu seperti ini:

NSTimer *timer;

    timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
                     target: self
                     selector: @selector(handleTimer:)
                     userInfo: nil
                     repeats: YES];
ennuikiller
sumber
14
Masih kuat ... 2014 juga!
Muruganandham K
5
#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
Dan
sumber
Entah bagaimana itu menciptakan mempertahankan siklus, sehingga MyViewControllertidak pernah dibatalkan alokasi.
Darrarski
5
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];

-(void)timerCalled
{
     NSLog(@"Timer Called");
     // Your Code
}
Mohit
sumber
dimana kamu menulis ini
Mohit
1
@ JigneshB jawaban ini hanya tentang cara menggunakan NSTimer bukan tentang menggunakannya di latar belakang
Mohit
saya menulis dalam metode latar belakang yaitu - (void) applicationDidEnterBackground: (UIApplication *) application {}
Jignesh B
dengan mode berulang YES
Jignesh B
Dokumentasi Apple sangat spesifik tentang tanda tangan metode panggilan balik. Anda salah.
Nikolai Ruhe
2

Jawabannya tidak ada waktu waktu tertentu di sini adalah pada jam berikutnya:

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];

Tentu saja, gantikan "doRefresh" dengan metode yang diinginkan kelas Anda

coba buat objek kalender sekali dan jadikan semua Unit statis untuk efisiensi.

menambahkan komponen satu jam berfungsi dengan baik, tidak perlu untuk tes tengah malam ( tautan )

gjpc
sumber