Objective-C에서는 마지막 구성 요소가 인수를받지 않는 메서드 이름을 선언 할 수 없습니다. 예를 들어, 다음은 불법입니다.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Objective-C가 이런 방식으로 설계된 이유는 무엇입니까? 아무도 제거 할 필요가 없다고 생각한 것은 스몰 토크의 유물 이었습니까?
이 제한은 Smalltalk에서 의미가 있습니다. Smalltalk는 메시지 호출 주위에 구분 기호가 없기 때문에 최종 구성 요소는 마지막 인수에 대한 단항 메시지로 해석됩니다. 예를 들어 BillyAndBobby take:'$100' andRun
는 BillyAndBobby take:('$100' andRun)
. 대괄호가 필요한 Objective-C에서는 문제가되지 않습니다.
지원 매개 변수가 선택기 구성 요소는 메소드 이름으로, 언어가 측정되는 모든 일반적인 방법으로 많은 우리를 얻을하지 않을 프로그래머 픽 (예를 들면 runWith:
보다는take:andRun
)는 프로그램의 기능적 의미 나 언어의 표현성에 영향을주지 않습니다. 실제로, 매개 변수가없는 구성 요소를 가진 프로그램은없는 구성 요소와 알파 동등합니다. 따라서 이러한 기능이 필요하지 않다는 답변에는 관심이 없습니다. 기능이 필요하지 않도록 메서드 이름을 작성하는 방법. 가장 큰 이점은 가독성과 쓰기 능력입니다 (가독성과 비슷합니다. 아시다시피). 자연어 문장과 훨씬 더 유사한 메서드 이름을 작성할 수 있다는 의미입니다. 이의 좋아 -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
하는 매트 갤러거는 지적 ( "코코아와 사랑"에-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
따라서 적절한 명사 바로 옆에 매개 변수를 배치합니다.
예를 들어 Apple의 Objective-C 런타임은 이러한 종류의 선택기를 완벽하게 처리 할 수 있습니다. 그렇다면 컴파일러는 어떻습니까? 메소드 이름에서도 지원하지 않는 이유는 무엇입니까?
#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;
}