Periksa apakah ada metode


111

Adakah cara agar saya dapat menguji apakah ada metode di Objective-C?

Saya mencoba menambahkan penjaga untuk melihat apakah objek saya memiliki metode sebelum memanggilnya.


Ada juga pertanyaan apakah ini adalah pendekatan yang tepat sejak awal, karena kelas Objective-C dapat merespons penyeleksi yang belum mereka deklarasikan (melalui - forwardInvocation:).
Donal Fellows

Jawaban:


189
if ([obj respondsToSelector:@selector(methodName:withEtc:)]) {
   [obj methodName:123 withEtc:456];
}

72

Ada juga instance pesan statisRespondToSelector: (SEL) selector Anda akan menyebutnya seperti ini:

[MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]

atau seperti ini:

[[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]

Ini mungkin berguna jika Anda ingin memanggil satu konstruktor atau yang lain tergantung pada ini (maksud saya, sebelum memiliki instance itu sendiri).


1
Apa perbedaan instanceRespondToSelector dari respondsToSelector?
CReaTuS

1
Perbedaan utamanya adalah bahwa yang satu adalah pesan instance (untuk menguji apakah pesan instance yang ditentukan memang ada) sedangkan yang lainnya adalah pesan kelas (untuk menguji apakah pesan kelas yang ditentukan memang ada).
Ricard Pérez del Campo

1
+1 Untuk [MyClass instanceRespondToSelector]. Saya membutuhkannya di dalam metode pembuatan init: Ketika subclassing mungkin diperlukan untuk memanggil satu metode super init daripada yang lain (yang tidak digunakan lagi), karena self belum dibuat dan respondsToSelector akan selalu mengembalikan NO.
LightMan

12

Gunakan respondsToSelector:. Dari dokumentasi :

respondsToSelector:

Mengembalikan nilai Boolean yang menunjukkan apakah penerima mengimplementasikan atau mewarisi metode yang dapat merespons pesan yang ditentukan.

- (BOOL)respondsToSelector:(SEL)aSelector

Parameters
aSelector - Selektor yang mengidentifikasi pesan.

Return Value
YES jika penerima mengimplementasikan atau mewarisi metode yang dapat merespons aSelector , jika tidak NO.


10

Anda sedang mencari respondsToSelector: -

if ([foo respondsToSelector: @selector(bar)] {
  [foo bar];
}

Seperti yang dikatakan Donal, hal di atas memberi tahu Anda bahwa foo pasti dapat menangani penerimaan pemilih bar. Namun, jika foo adalah proxy yang meneruskan bilah ke beberapa objek yang mendasari yang akan menerima pesan bilah, maka respondsToSelector: akan memberi tahu Anda TIDAK, meskipun pesan tersebut akan diteruskan ke objek yang merespons bilah.


1

Memeriksa pemilih dengan respondsToSelector biasanya hanya untuk metode delegasi. Anda tidak boleh menggunakan forwardInvocation atau proxy untuk metode delegasi. Jika Anda perlu menggunakan respondsToSelector dalam situasi lain, Anda mungkin ingin memastikan bahwa tidak ada cara yang lebih tepat untuk mendesain program Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.