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;
}