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.

teepusink
sumber
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];
}
kennytm
sumber
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).

Ricard Pérez del Campo
sumber
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.

Carl Norum
sumber
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.

Frank Shearar
sumber
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.

Eric
sumber