动态数据类型和静态数据类型
- 动态数据类型只有在运行时候才知道其类型和属性
- 静态数据类型在编译的时候就知道其类型和其属性,并在编译时可访问其属性
1、消息发送机制
id (动态数据类型)
id是指针,id*是指针的指针
id 有时很危险
NSString *s = @"ab";
id obj = s; //id为指向任何类型的指针,所以没有错误
NSArray *b = obj; //由于其实动态数据类型,所以运行时候才会知道其类型是什么,所以编译没有错误,但是运行时候就会有错误了,因为一个NSArray *指向一个NSString *显然是不合理的
为了避免这种运行的错误,当使用动态数据类型定义变量时候,先检查此对象的方法是否可以使用
如:
id obj = [NSStirng new];
//这里判断obj是可用
id obj = .......; //定义并初始化obj对象(任何类型)
[obj xxxx]; //对其发送任何方法(如果方法存在编译不会警告,否则会发出警告),等到运行时如果不支持xxxx任何方法的话,那么将会出错
NSString *string = @"hello world!";
[string xxxx]; //xxxx方法如果不存在那么会发出警告
otherType *p = (otherType *)string; //强制类型转换
[otherType xx] //即使otherType存在xx方法(编译不会错误),但是明显知道其实一个NSStirng *(运行时错误),所以很危险。
可以对id进行保护的两种方法:introspection (内省) 和protocol (协议)
- - (BOOL) isKindOfClass: classObj 判断是否是这个类或者这个类的子类的实例
if([obj isKindOfClass:[你想要确认的类 class]]) //参数为某个类的类方法,不能为实例方法,
{
//可以在这里将obj类型转换为所确认的类
}
- - (BOOL) isMemberOfClass: classObj 判断是否是这个类的实例
if([obj isMemberOfClass:[你想要确认的类 class]]) //参数为某个类的类方法,不能为实例方法,
{
//可以在这里将obj类型转换为所确认的类
}
- respondsToSelector
if ([obj respondsToSelector:@selector(xxxx)]) //判定obj是否对@selector选定的方法做出响应
{
[obj baseAPIdidStartRequest:self];
}
SEL及performSelector
- SEL是oc中的selector的类型
SEL xx = @selector(); //无参数的
SEL xx = @selector(xxxx:); //一个参数的
SEL xx = @selector(xxxx: xxxxx:); //两个参数的