使用动态绑定(id类型)
id类型:
id数据类型在OC中是一种通用的数据类型,它可以指代任何数据类型,只有在程序执行期间,可以确定它的真是数据类型,而且是可以改变的,因此这个过程就可以称作动态绑定。
下面定义两个不同类型的类:
Test_1:
#import <Foundation/Foundation.h>
@interface Test_1 : NSObject
- (void)print;
@end
#import "Test_1.h"
@implementation Test_1
- (void)print
{
NSLog(@"我是Test_1");
}
@end
Test_2:
#import <Foundation/Foundation.h>
@interface Test_2 : NSObject
- (void)print;
@end
#import "Test_2.h"
@implementation Test_2
- (void)print
{
NSLog(@"我是Test_2");
}
@end
main:
main:
#import <Foundation/Foundation.h>
#import "Test_1.h"
#import "Test_2.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
id _id ;
Test_1 *test1 = [[Test_1 alloc] init];
_id = test1;
[_id print];
Test_2 *test2 = [[Test_2 alloc] init];
_id = test2;
[_id print];
}
return 0;
}
输出结果为:
我是Test_1
我是Test_2
这说明id类型的变量在程序执行期间动态的改变了自己的数据类型,并向自己对应数
据类型的对象发送了print消息。
这里要注意一点:如果你显式的去定义一个实例(就是定义一个静态的类型即固定的数据类型)的时候,当你错误的向该对象发送消息的时候,程序会在编译阶段产生警告消息。但是,如果你动态的绑定一个数据类型(就好比一个id类型)的时候,程序只会在运行是产生警告,因为在编译阶段,编译器无法确定动态绑定的类型,因此可能会引发一系列的麻烦,你可能在程序运行是根本就没有注意到,当产品发布之后,用户发现这些问题的时候就麻烦了,解决方法下面来说。
解决动态绑定时的问题:
NSObject 类提供了一些方法来保障动态类型在程序运行时程序的完整性。
处理动态类型的方法:
-(BOOL) isKindOfClass:class-object
检查对象是不是class-object或其子类成员(class-object在运用时候可以通过[对象/类 class]来获取对象的类/类的对象)
-(BOOL) isMemberOfClass:class-object
检查对象是不是class-object的成员(注意不包括子类成员)
-(BOOL) respondsToSelector:Selector
检查对象是否能够响应selector(selector是一个SEL类型的值,通常由@selector指令产生的)
+(BOOL)instancesRespondToSelector:selector
检查指定的类是否能响应selector
-(id)performSelector:selector
将指定的对象应用selector指定的方法
-(id)performSelector:selector withObject:object
将指定的对象应用selector指定的方法,并传递参数object
-(id)performSelector:selector withObject:object1withObject:object2
将指定的对象应用selector指定的方法,并传递参数object1和object2
要判断两个对象是不是相同的类实例,可以做如下判断:
if([obj1 class] == [obj2 class]);
判断一个对象obj1是不是一个指定的类OBJ,可以做如下判断:
[obj1 isMemberOfClass:[OBJ class]]返回一个布尔值;
判断obj1是否响应sprint方法,可做如下判断:
[obj1 respondToSelector:@selector(sprint)];
performSelector方法允许你向对象发送指定的selector
如下:
SEL action;
id obj;
action = @selector(functionName);
[obj performSelector:action];