1. class反射
使用反射往往不需要导入头文件, 就可以剔除一些对象. 类似于分类, 不导入也会调用其中的 load 方法.
- 通过类名的字符串形式实例化对象。
Class class = NSClassFromString(@"student");
Student *stu = [[class alloc] init];
- 将类名变为字符串。
Class class =[Student class];
NSString *className = NSStringFromClass(class);
2. SEL的反射
使用@selector 在编译时查找所需的方法
- 通过方法的字符串形式实例化方法。
SEL selector = NSSelectorFromString(@"setName");
[stu performSelector:selector withObject:@"Mike"];
[[Person class] performSelectorOnMainThread:@selector(eat) withObject:nil waitUntilDone:YES];
- 将方法变成字符串。
NSStringFromSelector(@selector(setName:));
3. class 反射使用场景一: 使用简单的代号枚举类名
- 适用于使用简单的枚举类型或字符串, 匹配类名, 方便独立快捷地创建各自的类.
- 优点是, 不需要考虑类的具体名称, 直接按照类名对应的 key 来查找即可, 可以把 key 定义得通俗易懂, 方便代码的维护.
+ (NSDictionary*)modeList
{
return @{@"1":[PTVRoomContentMode defaultModeName],
STYLE_TYPE_ROOM_307 : @"PTVPandaRoomContentModel",
STYLE_TYPE_CAT_TEAM : @"PTVCatBrigadeContentModel",
STYLE_TYPE_ESPORTS : @"PTVESportsContentModel",
};
}
调用方式如下:
NSString* modename = [[PTVRoomContentMode modeList] objectForKey:style_type];
PTVRoomContentMode* mode = [NSClassFromString(modename) new];
4. class 反射使用场景二: 遍历plist里面的字符串, 生成目标的类.
对于继承自同一个父类(如 NSObject )的多个子模块, 或遵守同一个协议(如 <NSObject> )的子模块, 可以将类名保存在 plist 文件里面, 按需创建子模块.
NSArray<NSString *> *moduleNames = [NSArray arrayWithContentsOfFile:plistFile];
for (NSString* class in moduleNames) {
if (![class isKindOfClass:[NSString class]])
continue;
PXXRoomModule* module = [NSClassFromString(class) new];
[self loadModule:module];
}