Objective-c 方法调用&内省机制(introspection)&selector

//所有的objects都存储在heap里,因此永远使用指针来访问abjects
例:NSString *s = …; //statically typed
id obj = s; //not statically typed, but perfectly legal
//千万不要写成id *,那表示object的指针的指针


//程序在runtime才会决定执行怎样的code,遇到方法的调用[(pointer to aObject) method],编译器会调用一个C函数OBJC,这个函数首先会找到这个object的class,然后找到相应的method的implementation,如果在这个class或者所有的superclasses里面都没有找到相应的method,那么程序就会crash。


//强制转换指针类型是允许的(cast a pointer),但是如果你没有很好的控制它就很容易crash,因为编译器不会报错。
例:

id obj = ...;
NSString *s = (NSString *) obj;  //这是很危险的,这是编译器允许对obj调用NSString的方法,但如果obj所指向的object所属的class没有这样的方法,那么程序在运行时就会崩溃

例:

@interface Vehical
-(void) move;
@end

@interface Ship : Vehicle
-(void) shoot;
@end

Ship *s = [[Ship alloc] init];
[s shoot]; //没有问题,Ship类里有这个方法
[s ship]; //没有问题,Ship的父类Vehicle里有这个方法

Vehicle *v = s; //没有问题,s是一个vehicle
[v shoot]; //Compiler Warning!Vehicle类没有shoot方法,尽管v所指向的是ship。运行没问题但是编译器会报错。

id obj = ...;
[obj shoot]; //没有问题,编译器知道shoot这个方法是存在的,但是运行时候如果obj没有对应的方法,那么程序崩溃。
[obj someMethodNameThatNoObjectAnywhereRespondsTo]; //Compiler Warning!因为任何class都没有这个方法,编译器可以肯定会出错

NSString *hello = @"hello";
[helle shoot]; //Compiler Warning!因为hello的类里找不到shoot方法
Ship *helleShip = (Ship *)hello;//强制转换指针类型
[helloShip shoot]; //编译器不会报错因为helloShip是Ship指针有shoot方法,运行时会崩溃,因为指针所指向的NSString并没有shoot方法
[(id)hello shoot]; //同样不会报错但运行时会崩溃

内省机制(introspection)
//我们常常会用到id或者强制转换指针类型,但是为了避免程序崩溃,我们需要使用内省机制。
//所有继承于NSObject的objects都有以下三个方法
isKindofClass: object是否是某个class或它的子类
isMemberofClass: object是否就是这个类
respondsToSelector: object是否有所给的method的调用方法
例:if([obj isKindofClass: [NSString class]]) {…;} //使用名为class的方法来获得这一个类名
例:if([obj respondsToSelector:@selector(shoot)]) {…;} //使用@selector来传递方法名


//SEL是OC里selector的一种类型
例:SEL shootSelector = @selector(shoot);
SEL shootAtSelecor = @selector(shootAt:);
SEL moveToSelector = @selector(MoveTo:WithPenColor:);
//与SEL相关的函数
1. methods in NSObject
//[obj performSelector:selector]; (调用没有参数的函数)
//[obj performeSelector:selector withObejct:target]; (调用有一个id类型参数的函数)
2. methods in NSArray 使array里的所有元素都调用这一个方法
//[array makeObjectsPerformSelector:selector];
//[array makeObjectsPerformSelector:selector withObject:target]; /target is an id
3. in UIButton, -(void)addTarget:(id)anObject action:(SEL)action …;
例:[button target:self action:@selector(digitPressed:) …];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值