Dengan Xcode 6.3 ada anotasi baru yang diperkenalkan untuk lebih mengekspresikan maksud API di Objective-C (dan untuk memastikan dukungan Swift yang lebih baik tentu saja). Penjelasan itu tentu saja nonnull
, nullable
dan null_unspecified
.
Tetapi dengan Xcode 7, ada banyak peringatan yang muncul seperti:
Pointer tidak memiliki specifier tipe nullability (_Nonnull, _Nullable atau _Null_unspecified).
Selain itu, Apple menggunakan jenis penentu nullability lain, menandai kode C ( sumber ) mereka:
CFArrayRef __nonnull CFArrayCreate(
CFAllocatorRef __nullable allocator, const void * __nonnull * __nullable values, CFIndex numValues, const CFArrayCallBacks * __nullable callBacks);
Jadi, singkatnya, kami sekarang memiliki 3 anotasi pembatalan yang berbeda ini:
nonnull
,nullable
,null_unspecified
_Nonnull
,_Nullable
,_Null_unspecified
__nonnull
,__nullable
,__null_unspecified
Meskipun saya tahu mengapa dan di mana harus menggunakan anotasi yang mana, saya agak bingung dengan jenis anotasi mana yang harus saya gunakan, di mana dan mengapa. Inilah yang bisa saya kumpulkan:
- Untuk properti saya harus menggunakan
nonnull
,nullable
,null_unspecified
. - Untuk metode parameter saya harus menggunakan
nonnull
,nullable
,null_unspecified
. - Untuk metode C saya harus menggunakan
__nonnull
,__nullable
,__null_unspecified
. - Untuk kasus lain, seperti ganda pointer saya harus menggunakan
_Nonnull
,_Nullable
,_Null_unspecified
.
Tetapi saya masih bingung mengapa kita memiliki begitu banyak anotasi yang pada dasarnya melakukan hal yang sama.
Jadi pertanyaan saya adalah:
Apa perbedaan persis antara anotasi tersebut, cara menempatkannya dengan benar dan mengapa?
sumber
Jawaban:
Dari
clang
dokumentasi :, dan
Jadi untuk pengembalian metode dan parameter, Anda dapat menggunakan versi bergaris bawah ganda
__nonnull
/__nullable
/__null_unspecified
alih-alih yang bertanda tunggal, atau bukan yang bertanda bawah. Perbedaannya adalah bahwa yang bergaris bawah tunggal dan ganda perlu ditempatkan setelah definisi tipe, sedangkan yang bergaris bawah harus ditempatkan sebelum definisi tipe.Dengan demikian, deklarasi berikut ini setara dan benar:
Untuk parameter:
Untuk properti:
Namun hal-hal menyulitkan ketika pointer ganda atau blok mengembalikan sesuatu yang berbeda dari kekosongan terlibat, karena yang non-garis bawah tidak diperbolehkan di sini:
Mirip dengan metode yang menerima blok sebagai parameter, harap perhatikan bahwa
nonnull
/nullable
kualifikasi berlaku untuk blok, dan bukan tipe kembalinya, dengan demikian yang berikut ini setara:Jika blok memiliki nilai kembali, maka Anda dipaksa ke salah satu versi garis bawah:
Sebagai kesimpulan, Anda bisa menggunakan yang mana saja, asalkan kompiler dapat menentukan item untuk menetapkan kualifikasi.
sumber
_Null_unspecified
di Swift ini artinya opsional? non-opsional atau apa?Dari blog Swift :
sumber
Saya sangat menyukai artikel ini , jadi saya hanya menunjukkan apa yang penulis tulis: https://swiftunboxed.com/interop/objc-nullability-annotations/
null_unspecified:
menjembatani ke Swift, pilihan yang secara implisit terbuka. Ini standarnya .nonnull
: nilai tidak akan nol; menjembatani ke referensi reguler.nullable
: nilainya bisa nol; menjembatani ke opsional.null_resettable
: nilai tidak pernah dapat nol saat dibaca, tetapi Anda dapat mengaturnya ke nil untuk mengatur ulang. Berlaku hanya untuk properti.Notasi di atas, kemudian berbeda apakah Anda menggunakannya dalam konteks properti atau fungsi / variabel:
Penulis artikel juga memberikan contoh yang bagus:
sumber
Sangat berguna
dan ditutup dengan
Ini akan meniadakan perlunya level kode 'nullibis' :-) karena agak masuk akal untuk menganggap bahwa semuanya adalah non-null (atau
nonnull
atau_nonnull
atau__nonnull
) kecuali dinyatakan sebaliknya.Sayangnya ada pengecualian untuk ini juga ...
typedef
s tidak dianggap__nonnull
(catatan,nonnull
tampaknya tidak berfungsi, harus menggunakannya saudara tiri jelek)id *
membutuhkan nullibi eksplisit tetapi wow pajak dosa (_Nullable id * _Nonnull
<- tebak apa artinya ...)NSError **
selalu dianggap nullableJadi dengan pengecualian untuk pengecualian dan kata kunci yang tidak konsisten memunculkan fungsi yang sama, mungkin pendekatannya adalah dengan menggunakan versi jelek
__nonnull
/__nullable
/__null_unspecified
dan bertukar ketika kompiler mengeluh ...? Mungkin itu sebabnya mereka ada di header Apple?Cukup menarik, sesuatu memasukkannya ke dalam kode saya ... Saya benci menggarisbawahi dalam kode (Apple gaya lama C + + guy) jadi saya benar-benar yakin saya tidak mengetik ini tetapi mereka muncul (salah satu contoh beberapa):
Dan yang lebih menarik, di mana ia memasukkan __nullable salah ... (eek @!)
Saya benar-benar berharap saya bisa menggunakan versi non-garis bawah tetapi ternyata itu tidak terbang dengan kompiler karena ini ditandai sebagai kesalahan:
sumber