bob*_*obo 6 objective-c dynamic-binding
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之类的脚本语言相比.
Lou*_*arg 17
您对运行时和编译器感到困惑.运行时没有问题可以解决这个问题.问题是点符号(这是语法糖)需要编译器的类型信息来消除Objective-C对象和C结构之间的歧义.
如果你不使用点符号它的工作原理:
NSLog( @"%@ : %@\n", [exc name], [exc reason]) ;
Run Code Online (Sandbox Code Playgroud)
如果类型不是id,上面将生成警告,因为编译器知道它确实知道类型并且不能保证调度将起作用,但它将编译并运行.
从根本上说,编译器需要知道是否生成结构加载或Objective C调度,换句话说,使用点符号需要有足够的信息来确定对象和标量类型之间的差异.
bbu*_*bum 17
动态绑定不是动态类型的同义词.C是一种强类型语言,特别是参数或返回值的类型很重要,可能会严重影响代码生成.
属性专门用于消除歧义.作为其中的一部分,该决定将不会允许对使用的点语法id.
具体来说,它解决了这种情况:
@interface Foo
- (short) length;
@end
@interface Bar
- (unsigned long long) length;
@end
Run Code Online (Sandbox Code Playgroud)
鉴于以上两个单独的头文件,编译[anObject length]只会警告两个头文件都已导入.如果只导入了一个头文件,则将编译调用站点,返回标题中看到的类型.如果调用站点用于另一个方法,则将返回非常意外的结果.
点语法的限制消除了这种潜在的模糊性.这也是您通常不会看到方法的共变量声明的原因.C ABI只是不干净地支持它(据说,Objective-C在支持对象类型协方差方面表现不佳).
实际上,Objective-C开发人员很少使用该id类型.特定类型声明使编译器能够显着改进其代码验证.
| 归档时间: |
|
| 查看次数: |
967 次 |
| 最近记录: |