Objective-C использует динамическое связывание: то есть вызовы методов разрешаются во время выполнения.
Отлично.
И использование точечной нотации действительно сводится к вызову метода
Но почему тогда я не могу сделать что-то вроде этого:
#import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // Intercept the exception @try { @throw [ NSException exceptionWithName:@"Exception named ME!" reason:@"Because i wanted to" userInfo:nil ] ; } @catch( id exc ) // pointer to an exception object? { //NSLog( @"%@ : %@\n", exc.name, exc.reason ) ; // ILLEGAL: Request for member // 'name' in something not a structure or union.. // If objective-c uses dynamic binding, and dot notation // boils down to calling the getter, then // WHY do I have to cast to the concrete type here? // Only works if I cast to the concrete type NSException* NSException* nexc = (NSException*)exc ; NSLog( @"%@ : %@\n", nexc.name, nexc.reason ) ; } [pool drain]; return 0; }
Когда я слышу "динамическое связывание", я думаю, что "он должен вести себя как язык сценариев", и меня удивляет, насколько негибким кажется Objective-C по сравнению с языком сценариев, таким как JavaScript.
[(id)exc name]
, но не можете(id)exc.name
, является одной из причин, почему это хакерство, причем плохое, плохо продуманное. Предоставление более одного способа сделать одно и то же - обычно плохая идея, а тот факт, что эти два способа не являются симметричными, вызывает множество проблем и путаницы. - person johne   schedule 08.11.2009