Belajar Objective-C dan membaca kode sampel, saya perhatikan bahwa objek biasanya dibuat menggunakan metode ini:
SomeObject *myObject = [[SomeObject alloc] init];
dari pada:
SomeObject *myObject = [SomeObject new];
Apakah ada alasan untuk ini, karena saya telah membaca bahwa mereka setara?
objective-c
oop
willc2
sumber
sumber
Jawaban:
Ada banyak alasan di sini: http://macresearch.org/difference-between-alloc-init-and-new
Beberapa yang dipilih adalah:
new
tidak mendukung inisialisasi khusus (sepertiinitWithString
)alloc-init
lebih eksplisit daripadanew
Pendapat umum tampaknya adalah bahwa Anda harus menggunakan apa pun yang Anda sukai.
sumber
+newWithString:
juga, jika Anda sudah menerapkan-initWithString
. Tapi tidak begitu umum. Secara pribadi saya selalu menggunakannew
ketika initializer yang ditunjukinit
, hanya soo pendek dan manis.+newWithString:
. Itu mematahkan pemisahan kekhawatiran. Karena ketika Anda hanya ingin menggunakannya-init
, tidak ada alasan untuk tidak menggunakannya+new
.[[NSString alloc] initWithFormat:...]
dan[NSString stringWithFormat:...]
keduanya setara. Apakah Anda mengatakan Apple melanggar pemisahan kekhawatiran dan seharusnya tidak menerapkannya dengan cara ini? (Catatan: Saya tidak berusaha untuk merendahkan; Saya hanya ingin mendapatkan lebih banyak info, dan tahu apakah mengikuti petunjuk Apple terkadang merupakan ide yang buruk.)Pertanyaan yang sangat lama, tapi saya telah menulis beberapa contoh hanya untuk bersenang-senang - mungkin Anda akan menemukan itu berguna
Dalam fungsi utama kedua pernyataan:
dan
menghasilkan output yang sama:
sumber
[[InitAllocNewTest alloc] init]
tidak akan mengkompilasi sementara[InitAllocNewTest new]
tidak terpengaruh. (Permintaan maaf karena tidak ada jeda baris, dll.)+new
setara dengan+alloc/-init
dalamNSObject
implementasi Apple . Sangat tidak mungkin hal ini akan pernah berubah, tetapi tergantung pada tingkat paranoia Anda, dokumentasi Apple untuk+new
tampaknya memungkinkan perubahan implementasi (dan melanggar kesetaraan) di masa depan. Untuk alasan ini, karena "eksplisit lebih baik daripada implisit" dan untuk kelangsungan sejarah, komunitas Objective-C umumnya menghindari+new
. Anda dapat, bagaimanapun, biasanya melihat pendatang Jawa baru-baru ini ke Objective-C dengan penggunaan mereka+new
.sumber
+new
sudah ada sejak zaman NeXT. Jika ada+new
sesuatu yang merupakan pertanda seseorang yang sudah lama belajar objc; Saya melihat banyak orang yang baru mengenal bahasa ini, atau yang bahkan telah menulisnya selama bertahun-tahun tetapi jelas setelah boom iOS, tidak tahu apa+new
artinya. Kedua, karena+new
sudah sangat tua dan sejak masa NeXT, Apple akan sangat gila untuk mengubahnya dengan cara yang merusak kode lama, terutama mengingat basis kode mereka sendiri mungkin dikotori dengan itu.new
ungkapan itu berasal dari Smalltalk. Ini juga digunakan di Ruby, dan kedua Objective-C dan Ruby mendapatkan banyak sintaks dan konvensi dari Smalltalk.Seringkali, Anda harus meneruskan argumen
init
dan karenanya Anda akan menggunakan metode yang berbeda, seperti[[SomeObject alloc] initWithString: @"Foo"]
. Jika Anda terbiasa menulis ini, Anda terbiasa melakukannya dengan cara ini dan[[SomeObject alloc] init]
mungkin akan lebih alami[SomeObject new]
.sumber
Satu Jawaban Pendek adalah:
sumber
Sebagai catatan, saya pribadi menggunakan
[Foo new]
jika saya ingin sesuatu di init dilakukan tanpa menggunakan nilai pengembaliannya di mana saja. Jika Anda tidak menggunakan pengembalian di[[Foo alloc] init]
mana pun maka Anda akan mendapat peringatan. Lebih atau kurang, saya gunakan[Foo new]
untuk permen mata.sumber
Saya sangat terlambat untuk ini tetapi saya ingin menyebutkan bahwa yang baru sebenarnya tidak aman di Obj-C dengan dunia Swift. Swift hanya akan membuat metode init default jika Anda tidak membuat inisialisasi lainnya. Memanggil baru di kelas cepat dengan penginisialisasi khusus akan menyebabkan crash. Jika Anda menggunakan mengalokasikan / init maka kompiler akan dengan benar mengeluh bahwa init tidak ada.
sumber
Jika baru melakukan pekerjaan untuk Anda, maka itu akan membuat kode Anda lebih kecil juga. Jika Anda akan memanggil
[[SomeClass alloc] init]
banyak tempat berbeda dalam kode Anda, Anda akan membuat Hot Spot dalam implementasi baru - yaitu, dalam runtc objc - yang akan mengurangi jumlah kesalahan cache Anda.Dalam pemahaman saya, jika Anda perlu menggunakan penggunaan penginisialisasi kustom
[[SomeClass alloc] initCustom]
.Jika tidak, gunakan
[SomeClass new]
.sumber
init
fungsi default , dan gunakan itu.[[SomeClass alloc] init];
Jika Anda membutuhkan parameter, tetap tidak pernah melakukan sesuatu seperti itu, lakukan[[SomeClass alloc] initWith:...];
. Terakhir, jika Anda menggantiinit
fungsi dengan implementasi kustom, Anda dapat memanggilnew
saat membuat objek, dan itu masih akan memanggilinit
implementasi kustom .