Saya perlu waktu antara dua peristiwa, misalnya, penampilan UIView dan reaksi pertama pengguna.
Bagaimana saya bisa mencapainya di Objective-C?
ios
objective-c
Ilya Suzdalnitski
sumber
sumber
fabs(...)
untuk mendapatkan nilai absolut float. Misalnya.NSTimeInterval timeInterval = fabs([start timeIntervalSinceNow]);
[NSDate date]
dapat menyebabkan sulit untuk melacak bug, lihat jawaban ini untuk info lebih lanjut.Anda tidak boleh mengandalkan
[NSDate date]
untuk tujuan pengaturan waktu karena ini dapat membuat laporan yang berlebih atau kurang dilaporkan. Bahkan ada kasus di mana komputer Anda tampaknya akan melakukan perjalanan waktu karena waktu yang berlalu akan menjadi negatif! (Misalnya, jika jam bergerak mundur selama penghitungan waktu.)Menurut Aria Haghighi dalam kuliah "Pengenalan Gerakan iOS Lanjutan" dari kursus Musim Dingin 2013 Stanford iOS (34:00), Anda harus menggunakan
CACurrentMediaTime()
jika Anda membutuhkan interval waktu yang akurat.Tujuan-C:
Cepat:
Alasannya adalah
[NSDate date]
sinkronisasi di server, sehingga dapat menyebabkan "cegukan sinkronisasi waktu" yang dapat menyebabkan bug yang sangat sulit dilacak.CACurrentMediaTime()
, di sisi lain, adalah waktu perangkat yang tidak berubah dengan sinkronisasi jaringan ini.Anda akan perlu menambahkan pada kerangka QuartzCore untuk pengaturan target Anda.
sumber
[NSDate date]
dalam blok penyelesaian dalam blok pengiriman, saya mendapatkan waktu "saat ini" yang sama yang dilaporkan[NSDate date]
segera sebelum eksekusi mencapai titik di mana blok saya dibuat.CACurrentMediaTime()
memecahkan masalah ini.CACurrentMediaTime()
berhenti berdetak bila perangkat memasuki mode sleep. Jika Anda menguji dengan perangkat terputus dari komputer, kunci, lalu tunggu ~ 10 menit Anda akan menemukan bahwaCACurrentMediaTime()
tidak sesuai dengan waktu jam dinding.Gunakan
timeIntervalSinceDate
metodenyaNSTimeInterval
hanya adouble
, definisikanNSDate
seperti ini:sumber
Bagi siapa pun yang datang ke sini mencari implementasi getTickCount () untuk iOS, inilah milik saya setelah menyatukan berbagai sumber.
Sebelumnya saya memiliki bug dalam kode ini (saya dibagi dengan 10.00000 dulu) yang menyebabkan beberapa quantisation dari output pada iPhone 6 saya (mungkin ini bukan masalah pada iPhone 4 / etc atau saya hanya tidak pernah menyadarinya). Perhatikan bahwa dengan tidak melakukan pembagian itu terlebih dahulu, ada risiko overflow jika pembilang timebase cukup besar. Jika ada yang penasaran, ada tautan dengan informasi lebih lanjut di sini: https://stackoverflow.com/a/23378064/588476
Mengingat informasi itu, mungkin lebih aman menggunakan fungsi Apple
CACurrentMediaTime
!Saya juga melakukan benchmark pada
mach_timebase_info
panggilan dan membutuhkan sekitar 19ns pada iPhone 6 saya, jadi saya menghapus kode (bukan threadsafe) yang merupakan caching output dari panggilan itu.Berhati-hatilah dengan potensi risiko melimpah tergantung pada output panggilan timebase. Saya curiga (tetapi tidak tahu) bahwa itu mungkin konstan untuk setiap model iPhone. di iPhone 6 saya itu
125/3
.Solusi yang digunakan
CACurrentMediaTime()
cukup sepele:sumber
mach_timebase_info()
akan mengatur ulang pass-inmach_timebase_info_data_t
ke{0,0}
sebelum menyetelnya ke nilai aktual, yang dapat menyebabkan pembagian dengan nol jika kode dipanggil dari banyak utas. Gunakandispatch_once()
sebagai gantinya (atauCACurrentMediaTime
yang hanya diubah waktu menjadi detik).Untuk pengukuran waktu perkise (seperti GetTickCount), lihat juga mach_absolute_time dan Tanya Jawab Apple ini: http://developer.apple.com/qa/qa2004/qa1398.html .
sumber
gunakan fungsi timeIntervalSince1970 dari kelas NSDate seperti di bawah ini:
pada dasarnya, inilah yang saya gunakan untuk membandingkan perbedaan dalam detik antara 2 tanggal yang berbeda. periksa juga tautan ini di sini
sumber
Jawaban lainnya benar (dengan peringatan *). Saya menambahkan jawaban ini hanya untuk menunjukkan contoh penggunaan:
Di konsol debugger, Anda melihat sesuatu seperti ini:
* Peringatan: Seperti yang disebutkan sebelumnya, gunakan
NSDate
untuk menghitung waktu yang telah berlalu hanya untuk tujuan kasual. Salah satu tujuan tersebut mungkin pengujian umum, profil mentah, di mana Anda hanya ingin gambaran kasar tentang berapa lama suatu metode dibutuhkan.Risikonya adalah bahwa pengaturan waktu jam perangkat saat ini dapat berubah setiap saat karena sinkronisasi jam jaringan. Sehingga
NSDate
waktu bisa melompat maju atau mundur kapan saja.sumber