对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现。
这些知识是看别的博主写的,然后自己理解再写一遍。
新建两个类,Person,Teacher。Teacher继承与Person。
1.Person类
//
// Person.h
// iOS动态类型
//
// Created by 987trip_dev_mac on 15/6/16.
// Copyright (c) 2015年 987trip_dev_mac. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, strong) NSString *name;
-(void)setName:(NSString *)name;
@end
//
// Person.m
// iOS动态类型
//
// Created by 987trip_dev_mac on 15/6/16.
// Copyright (c) 2015年 987trip_dev_mac. All rights reserved.
//
#import "Person.h"
@implementation Person
-(void)setName:(NSString *)name{
self.name = name;
}
@end
2.新建Teacher类
//
// Teacher.h
// iOS动态类型
//
// Created by 987trip_dev_mac on 15/6/16.
// Copyright (c) 2015年 987trip_dev_mac. All rights reserved.
//
#import "Person.h"
@interface Teacher : Person
-(void)teach;
@end
//
// Teacher.m
// iOS动态类型
//
// Created by 987trip_dev_mac on 15/6/16.
// Copyright (c) 2015年 987trip_dev_mac. All rights reserved.
//
#import "Teacher.h"
@implementation Teacher
-(void)teach{
NSLog(@"我是教数学的");
}
@end
3.Students类
//
// Students.h
// iOS动态类型
//
// Created by 987trip_dev_mac on 15/6/16.
// Copyright (c) 2015年 987trip_dev_mac. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Students : NSObject
-(void)learning;
@end
//
// Students.m
// iOS动态类型
//
// Created by 987trip_dev_mac on 15/6/16.
// Copyright (c) 2015年 987trip_dev_mac. All rights reserved.
//
#import "Students.h"
@implementation Students
-(void)learning{
NSLog(@"我是学生,我爱学习");
}
@end
/**
Person,Teacher这两个类。Teacher是继承与Person。
*/
Person *person = [[Person alloc]init];
Teacher *teacher = [[Teacher alloc]init];
判断对象类类型
- (BOOL)isKindOfClass:(Class)aClass;isKindOfClass是检测属不属于这个类的子类。就算是继承都是可以检测出来
- (BOOL)isMemberOfClass:(Class)aClass;isMemberOfClass判断是否是属于这类的实例,是否跟父类有关系他不管。
/**
Person,Teacher这两个类。Teacher是继承与Person。
*/
Person *person = [[Person alloc]init];
Teacher *teacher = [[Teacher alloc]init];
//isMemberOfClass方法。
if ([teacher isMemberOfClass:[Teacher class]]) {
NSLog(@"teacher Teacher类的成员");
}
if ([teacher isMemberOfClass:[Person class]]) {
NSLog(@"teacher Person类的成员");
}
if ([teacher isMemberOfClass:[NSObject class]]) {
NSLog(@"teacher NSObject类的成员");
}
//只有第一个判断打印出来,isMemberOfClass判断是否是属于这类的实例,是否跟父类有关系他不管。
//isKindOfClass方法
if ([teacher isKindOfClass:[Teacher class]]) {
NSLog(@"teacher 是 Teacher类或Teacher的子类");
}
if ([teacher isKindOfClass:[Person class]]) {
NSLog(@"teacher 是 Person类或Person的子类");
}
if ([teacher isKindOfClass:[NSObject class]]) {
NSLog(@"teacher 是 NSObject类或NSObject的子类");
}
// isKindOfClass 是检测属不属于这个类的子类。就算是继承都是可以检测出来
判断实例是否有这个方法
- (BOOL)respondsToSelector:(SEL)aSelector;判断实例是否有这样方法
if ([person respondsToSelector:@selector(setName:)]==YES) {
NSLog(@"Person 有这个方法 setName");
}
if ([Teacher respondsToSelector:@selector(alloc)]==YES) {
NSLog(@"Teacher 有这个方法 alloc");
}
+ (BOOL)instancesRespondToSelector:(SEL)aSelector;判断类是否有这个方法。此方法是类方法,不能用在类的对象
if ([Person instancesRespondToSelector:@selector(teach)]==YES) {
NSLog(@"Person 有这个方法 ");
}
if ([Teacher instancesRespondToSelector:@selector(teach)]==YES) {
NSLog(@"Teacher 有这个teach方法");
}
if ([Teacher instancesRespondToSelector:@selector(setName:)]==YES) {
NSLog(@"Teacher 有这个setName方法");
}
1. NSClassFromString
这个方法判断类是否存在,如果存在就动态加载的,不存为就返回一个空对象;
优点:
1, 弱化连接,因此并不会把没有的Framework也link到程序中。
2,不需要使用import,因为类是动态加载的,只要存在就可以加载。因此如果你的toolchain中没有某个类的头文件定义,而你确信这个类是可以用的,那么也可以用这种方法。
//动态加载实例
//NSClassFromString(<#NSString *aClassName#>)
//这个方法判断类是否存在,如果存在就动态加载的,不存为就返回一个空对象;
id student = [[NSClassFromString(@"Students") alloc]init];
if ([student isMemberOfClass:[NSClassFromString(@"Students") class]]) {
NSLog(@"存在 Students 这个类");
}
//等价于
id students = [[Students alloc]init]
NSSelectorFromString
这个方法是上个方法的补充,也是动态加载实例方法。
//动态加载实例的方法
SEL sel = NSSelectorFromString(@"learning");
if ([student respondsToSelector:sel]) {
[student performSelector:sel withObject:student];
NSLog(@"存在这个方法");
}