Di Objective-C, Anda tidak bisa mendeklarasikan nama metode di mana komponen terakhir tidak mengambil argumen. Misalnya, berikut ini ilegal.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Mengapa Objective-C dirancang seperti ini? Apakah itu hanya artefak Smalltalk yang tidak ada yang melihat perlu disingkirkan?
Batasan ini masuk akal di Smalltalk, karena Smalltalk tidak memiliki pembatas di sekitar pemanggilan pesan, jadi komponen terakhir akan ditafsirkan sebagai pesan unary ke argumen terakhir. Misalnya, BillyAndBobby take:'$100' andRun
akan diurai sebagai BillyAndBobby take:('$100' andRun)
. Ini tidak masalah di Objective-C di mana tanda kurung siku diperlukan.
Komponen pendukung parameterless pemilih tidak akan mendapatkan kita banyak dalam semua cara yang biasa bahasa diukur, sebagai nama sebuah metode programmer picks (misalnya runWith:
daripadatake:andRun
) tidak mempengaruhi semantik fungsional suatu program, maupun ekspresi bahasa. Memang, program dengan komponen tanpa parameter adalah alfa yang setara dengan program tanpa komponen. Jadi saya tidak tertarik dengan jawaban yang menyatakan bahwa fitur seperti itu tidak diperlukan (kecuali itu adalah alasan yang dinyatakan oleh desainer Objective-C; apakah ada yang kebetulan mengenal Brad Cox atau Tom Love? Apakah mereka ada di sini?) Atau yang mengatakan cara menulis nama metode sehingga fiturnya tidak diperlukan. Manfaat utama adalah keterbacaan dan penulisan (yang seperti keterbacaan, hanya ... Anda tahu), karena itu berarti Anda dapat menulis nama metode yang bahkan lebih mirip dengan kalimat bahasa alami. Yang seperti -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
(yang ditunjukkan Matt Gallagher di "Cocoa With Love"-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
, sehingga menempatkan parameter tepat di sebelah kata benda yang sesuai.
Runtime Objective-C Apple (misalnya) sangat mampu menangani pemilih semacam ini, jadi mengapa tidak kompilernya? Mengapa tidak mendukung mereka dalam nama metode juga?
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Potrzebie : NSObject
-(void)take:(id)thing;
@end
@implementation Potrzebie
+(void)initialize {
SEL take_andRun = NSSelectorFromString(@"take:andRun");
IMP take_ = class_getMethodImplementation(self, @selector(take:));
if (take_) {
if (NO == class_addMethod(self, take_andRun, take_, "@@:@")) {
NSLog(@"Couldn't add selector '%@' to class %s.",
NSStringFromSelector(take_andRun),
class_getName(self));
}
} else {
NSLog(@"Couldn't find method 'take:'.");
}
}
-(void)take:(id)thing {
NSLog(@"-take: (actually %@) %@",NSStringFromSelector(_cmd), thing);
}
@end
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Potrzebie *axolotl=[[Potrzebie alloc] init];
[axolotl take:@"paradichloroaminobenzaldehyde"];
[axolotl performSelector:NSSelectorFromString(@"take:andRun")
withObject:@"$100"];
[axolotl release];
[pool release];
return 0;
}
takeAndRunWith:(id)theMoney
dantakeAndDon'tComplainAbout:(id)yourMedicine
. Secara tata bahasa canggung, pastinya.- (void) :(id)theMoney;
atau- (void) :(id)obj1 :(id)obj2;
. Jadi penyeleksi hanya terdiri dari titik dua saja. ;-)Jawaban:
Ini Brad Cox. Jawaban asli saya salah memahami pertanyaan itu. Saya berasumsi reallyFast adalah ekstensi yang di-hardcode untuk memicu pengiriman pesan yang lebih cepat, bukan semacam gula sintaksis. Jawaban sebenarnya adalah Smalltalk tidak mendukungnya, mungkin karena pengurai tidak dapat menangani ambiguitas (yang diasumsikan). Meskipun tanda kurung siku OC akan menghilangkan ambiguitas, saya sama sekali tidak berpikir untuk berangkat dari struktur kata kunci Smalltalk.
sumber
21 tahun pemrograman Objective-C dan pertanyaan ini tidak pernah terlintas di benak saya. Mengingat desain bahasa, kompilernya benar dan fungsi runtime salah ().
Gagasan argumen berselang-seling dengan nama metode selalu berarti bahwa, jika ada setidaknya satu argumen, argumen terakhir selalu merupakan bagian terakhir dari sintaks pemanggilan metode.
Tanpa terlalu memikirkannya, saya yakin ada beberapa kesalahan sintaksis dengan tidak menerapkan pola saat ini. Paling tidak, ini akan membuat kompiler lebih sulit untuk menulis karena sintaks apapun yang memiliki elemen opsional yang disisipkan dengan ekspresi selalu lebih sulit untuk diurai. Bahkan mungkin ada casing tepi yang mencegahnya rata. Tentu saja, Obj-C ++ akan membuatnya lebih menantang, tetapi itu tidak terintegrasi dengan bahasa sampai bertahun-tahun setelah sintaks dasar sudah ditetapkan.
Sejauh mengapa Objective-C dirancang seperti ini, saya curiga jawabannya adalah bahwa perancang asli bahasa hanya tidak mempertimbangkan untuk membiarkan sintaks yang disisipkan melampaui argumen terakhir itu.
Itu tebakan terbaik. Saya akan bertanya kepada salah satu dari mereka dan memperbarui jawaban saya ketika saya mengetahui lebih lanjut.
Saya bertanya kepada Brad Cox tentang ini dan dia sangat murah hati dalam menanggapi secara detail (Terima kasih, Brad !!):
Bacalah jawaban Brad!
sumber
-myObjectWithDelegate: (id) foo wantsYouToDoSomethingWith: (id) bar
. Hal ini menyebabkan ketidakkonsistenan yang mencolok dalam nama metode jika Anda memiliki metode dalam protokol yang tidak memerlukan parameter lain. Lihat NSTableViewDataSource sebagai contoh. Satu metode tidak mengikuti pola rapi yang bagus dari semua metode lainnya.Hanya untuk informasi Anda, runtime sebenarnya tidak peduli dengan penyeleksi, string C apa pun valid, Anda juga dapat membuat pemilih seperti itu: "== + === + ---__-- ¨¨¨¨ ¨ ^ :::::: "tanpa argumen runtime akan menerimanya, kompilator tidak bisa atau tidak mungkin untuk mengurai. Sama sekali tidak ada pemeriksaan kewarasan dalam hal penyeleksi.
sumber
Saya berasumsi mereka tidak didukung di Objective-C karena mereka juga tidak tersedia di Smalltalk. Tetapi itu memiliki alasan yang berbeda dari yang Anda pikirkan: mereka tidak dibutuhkan. Yang dibutuhkan adalah dukungan untuk metode dengan argumen 0, 1, 2, 3, .... Untuk setiap jumlah argumen, sudah ada sintaks yang berfungsi untuk memanggilnya. Menambahkan sintaks lain hanya akan menyebabkan kebingungan yang tidak perlu.
Jika Anda menginginkan pemilih tanpa parameter multi-kata, mengapa berhenti dengan satu kata tambahan? Seseorang mungkin akan menanyakan itu
juga menjadi didukung (yaitu selektor adalah urutan kata, beberapa dengan titik dua dan parameter, dan yang lainnya tidak). Meskipun ini mungkin terjadi, saya berasumsi bahwa tidak ada yang menganggapnya bermanfaat.
sumber
and
danor
akan menjadi batu sandungan tertentu). Ini akan terjadi jauh lebih sedikit jika hanya komponen akhir dari nama metode yang diizinkan untuk tidak memiliki parameter, karena akan cenderung terdiri dari banyak kata.