Apa alasan yang tepat untuk menggunakan dispatch_once di accessor instance bersama dari singleton di bawah ARC?
+ (MyClass *)sharedInstance
{
// Static local predicate must be initialized to 0
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
Bukankah itu ide buruk untuk membuat singleton secara asinkron di latar belakang? Maksud saya apa yang terjadi jika saya meminta instance bersama itu dan segera mengandalkannya, tetapi dispatch_once membutuhkan waktu hingga Natal untuk membuat objek saya? Itu tidak segera kembali kan? Setidaknya itu tampaknya menjadi inti dari Grand Central Dispatch.
Jadi mengapa mereka melakukan ini?
ios
objective-c
singleton
automatic-ref-counting
Anggota yang Bangga
sumber
sumber
Note: static and global variables default to zero.
Jawaban:
dispatch_once()
benar-benar sinkron. Tidak semua metode GCD melakukan hal-hal secara asinkron (dalam hal ini,dispatch_sync()
sinkron). Penggunaandispatch_once()
menggantikan idiom berikut:Manfaat
dispatch_once()
lebih dari ini adalah lebih cepat. Ini juga semantik bersih, karena juga melindungi Anda dari beberapa utas yang melakukan alokasi init Instance Anda bersama - jika mereka semua mencoba pada waktu yang tepat. Itu tidak akan membiarkan dua instance dibuat. Gagasan keseluruhandispatch_once()
adalah "melakukan sesuatu sekali dan hanya sekali", itulah tepatnya yang kami lakukan.sumber
dispatch_once()
itu sangat sederhana (terutama karena Xcode bahkan akan secara otomatis melengkapinya menjadi potongan kode lengkap untuk Anda) dan berarti Anda bahkan tidak pernah harus mempertimbangkan apakah metode ini perlu thread-safe.+initialize
terjadi sebelum kelas disentuh, bahkan jika Anda belum mencoba membuat instance bersama Anda. Secara umum, inisialisasi malas (menciptakan sesuatu hanya bila diperlukan) lebih baik. Kedua, bahkan klaim kinerja Anda tidak benar.dispatch_once()
Dibutuhkan hampir persis jumlah waktu yang sama mengatakanif (self == [MyClass class])
dalam+initialize
. Jika Anda sudah memiliki+initialize
, maka ya membuat instance bersama ada lebih cepat, tetapi sebagian besar kelas tidak.Karena itu hanya akan berjalan sekali. Jadi, jika Anda mencoba dan mengaksesnya dua kali dari utas yang berbeda itu tidak akan menimbulkan masalah.
Mike Ash memiliki deskripsi lengkap dalam posting blog Care and Feeding of Singletons .
Tidak semua blok GCD dijalankan secara tidak sinkron.
sumber