Apakah ada cara untuk memanggil blok dengan parameter primitif setelah penundaan, seperti menggunakan performSelector:withObject:afterDelay:
tetapi dengan argumen seperti int
/ double
/ float
?
734
Apakah ada cara untuk memanggil blok dengan parameter primitif setelah penundaan, seperti menggunakan performSelector:withObject:afterDelay:
tetapi dengan argumen seperti int
/ double
/ float
?
Jawaban:
Saya pikir Anda sedang mencari
dispatch_after()
. Ini membutuhkan blok Anda untuk tidak menerima parameter, tetapi Anda bisa membiarkan blok menangkap variabel-variabel itu dari lingkup lokal Anda.Lebih lanjut: https://developer.apple.com/documentation/dispatch/1452876-dispatch_after
sumber
dispatch_time(DISPATCH_TIME_NOW, 10ull * NSEC_PER_SEC)
potongan jahat. Apakah tidak ada cara yang lebih bersih untuk ini?dispatch_get_current_queue()
selalu mengembalikan antrean tempat kode dijalankan. Jadi ketika kode ini dijalankan dari utas utama, blok juga akan dieksekusi pada utas utama.dispatch_get_current_queue()
sudah ditinggalkan sekarangAnda dapat menggunakan
dispatch_after
untuk memanggil blok nanti. Di Xcode, mulailah mengetikdispatch_after
dan tekanEnter
untuk lengkapi otomatis sebagai berikut:Inilah contoh dengan dua pelampung sebagai "argumen." Anda tidak harus bergantung pada jenis makro apa pun, dan maksud kode itu cukup jelas:
Swift 3, Swift 4
Cepat 2
Tujuan C
sumber
NSEC_PER_SEC * 0.5
akan bekerja sama denganNSEC_PER_MSEC * 500
. Meskipun Anda benar untuk mencatat bahwadispatch_time
mengharapkan integer 64-bit, nilai yang diharapkan dalam nanodetik.NSEC_PER_SEC
didefinisikan sebagai1000000000ull
, dan mengalikannya dengan konstanta floating-point0.5
secara implisit akan melakukan aritmatika floating-point, menghasilkan500000000.0
, sebelum secara eksplisit dilemparkan kembali ke integer 64-bit. Jadi bisa diterima menggunakan sebagian kecil dariNSEC_PER_SEC
.Bagaimana dengan menggunakan pustaka cuplikan kode bawaan Xcode?
Pembaruan untuk Swift:
Banyak suara menginspirasi saya untuk memperbarui jawaban ini.
Pustaka cuplikan kode Xcode bawaan
dispatch_after
hanya untukobjective-c
bahasa. Orang juga dapat membuat Cuplikan Kode Kustom untukSwift
.Tulis ini dalam Xcode.
Seret kode ini dan letakkan di area pustaka potongan kode.
Di bawah daftar cuplikan kode, akan ada entitas baru bernama
My Code Snippet
. Edit ini untuk judul. Untuk saran saat Anda mengetik Xcode, isikanCompletion Shortcut
.Untuk info lebih lanjut, lihat CreatingaCustomCodeSnippet .
Perbarui Swift 3
Seret kode ini dan letakkan di area pustaka potongan kode.
sumber
Memperluas jawaban Jaime Cham, saya membuat kategori + Blok NSObject seperti di bawah ini. Saya merasa metode ini lebih cocok dengan
performSelector:
metode NSObject yang adaNSObject + Blocks.h
NSObject + Blocks.m
dan gunakan seperti ini:
sumber
delay
harus dariNSTimeInterval
(yang merupakandouble
).#import <UIKit/UIKit.h>
tidak dibutuhkan. Dan, saya tidak mengerti mengapa ini- (void)performBlock:(void (^)())block;
bisa berguna, jadi bisa dihapus dari header.Mungkin lebih sederhana daripada melalui GCD, di kelas di suatu tempat (misalnya "Util"), atau Kategori di Obyek:
Jadi untuk digunakan:
sumber
Untuk Swift, saya telah membuat fungsi global, tidak ada yang istimewa, menggunakan
dispatch_after
metode ini. Saya lebih suka ini karena mudah dibaca dan mudah digunakan:Yang bisa Anda gunakan sebagai berikut:
sumber
after
. Maka Anda dapat menulis:after(2.0){ print("do somthing") }
Inilah 2 sen saya = 5 metode;)
Saya suka merangkum detail-detail ini dan minta AppCode memberi tahu saya cara menyelesaikan kalimat saya.
sumber
PerformSelector: WithObject selalu mengambil objek, jadi untuk memberikan argumen seperti int / double / float dll ..... Anda dapat menggunakan sesuatu seperti ini.
// NSNumber adalah objek ..
Dengan cara yang sama Anda dapat menggunakan [NSNumber numberWithInt:] dll .... dan dalam metode penerima Anda dapat mengonversi angka ke dalam format Anda sebagai [number int] atau [number double].
sumber
Fungsi dispatch_after mengirimkan objek blok ke antrian pengiriman setelah periode waktu tertentu. Gunakan kode di bawah ini untuk melakukan beberapa pengambilan terkait UI setelah 2,0 detik.
Di cepat 3.0:
sumber
mainQueue,
bukannyamainQueue)
Inilah cara Swift 3 untuk mengantri kerja setelah penundaan.
sumber
Berikut ini adalah bantuan praktis untuk mencegah panggilan GCD yang menjengkelkan berulang kali:
Sekarang Anda cukup menunda kode Anda di utas utama seperti ini:
Jika Anda ingin menunda kode Anda ke utas berbeda :
Jika Anda lebih suka Kerangka yang juga memiliki beberapa fitur yang lebih berguna maka checkout HandySwift . Anda dapat menambahkannya ke proyek Anda melalui Carthage lalu menggunakannya persis seperti pada contoh di atas:
sumber
Ada yang bagus dalam framework BlocksKit.
BlocksKit
(dan kelas)
BBlocksKit.m
sumber
Di swift 3, Kita cukup menggunakan fungsi DispatchQueue.main.asyncAfter untuk memicu fungsi atau tindakan apa pun setelah penundaan 'n' detik. Di sini, dalam kode, kami telah menetapkan penundaan setelah 1 detik. Anda memanggil fungsi apa pun di dalam tubuh fungsi ini yang akan memicu setelah penundaan 1 detik.
sumber
Xcode 10.2 dan Swift 5 ke atas
sumber
Anda bisa membungkus argumen di kelas Anda sendiri, atau membungkus pemanggilan metode dalam metode yang tidak perlu diteruskan dalam tipe primitif. Kemudian panggil metode itu setelah penundaan Anda, dan di dalam metode itu lakukan pemilih yang ingin Anda lakukan.
sumber
Inilah cara Anda dapat memicu blok setelah penundaan di Swift:
Termasuk sebagai fungsi standar dalam repo saya .
sumber
Swift 3 & Xcode 8.3.2
Kode ini akan membantu Anda, saya juga menambahkan penjelasan
sumber
Saya percaya penulis tidak bertanya bagaimana menunggu waktu fraksional (penundaan), melainkan bagaimana cara melewatkan skalar sebagai argumen pemilih (withObject :) dan cara tercepat dalam tujuan modern C adalah:
pemilih Anda harus mengubah parameternya ke NSNumber, dan mengambil nilainya menggunakan pemilih seperti floatValue atau doubleValue
sumber