博客> iOS面试题:反射是什么?可以举出几个应用场景么?
iOS面试题:反射是什么?可以举出几个应用场景么?
5分钟前 评论:0 阅读:159 Monkey2020
iOS面试题

系统Foundation框架为我们提供了一些方法反射的API,我们可以通过这些API执行将字符串转为SEL等操作。由于OC语言的动态性,这些操作都是发生在运行时的。

/SEL和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector);
FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName);
/Class和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromClass(Class aClass);
FOUNDATION_EXPORT Class __nullable NSClassFromString(NSString *aClassName);
/Protocol和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromProtocol(Protocol *proto) NS_AVAILABLE(10_5, 2_0);
FOUNDATION_EXPORT Protocol * __nullable NSProtocolFromString(NSString *namestr) NS_AVAILABLE(10_5, 2_0);

通过这些方法,我们可以在运行时选择创建那个实例,并动态选择调用哪个方法。这些操作甚至可以由服务器传回来的参数来控制,我们可以将服务器传回来的类名和方法名,实例为我们的对象。

/假设从服务器获取JSON串,通过这个JSON串获取需要创建的类为ViewController,并且调用这个类的getDataList方法。
Class class = NSClassFromString(@"ViewController");
ViewController *vc = [[class alloc] init];
SEL selector = NSSelectorFromString(@"getDataList");
[vc performSelector:selector];

反射机制使用技巧

假设有一天公司产品要实现一个需求:根据后台推送过来的数据,进行动态页面跳转,跳转到页面后根据返回到数据执行对应的操作。

遇到这样奇葩的需求,我们当然可以问产品都有哪些情况执行哪些方法,然后写一大堆if else判断或switch判断。 但是这种方法实现起来太low了,而且不够灵活,假设后续版本需求变了,还要往其他已有页面中跳转,这不就傻眼了吗.... 这种情况反射机制就派上用场了,我们可以用反射机制动态的创建类并执行方法。当然也可以通过runtime来实现这个功能,但是我们当前需求反射机制已经足够满足需求了,如果遇到更加复杂的需求可以考虑用runtime来实现。 这时候就需要和后台配合了,我们首先需要和后台商量好返回的数据结构,以及数据格式、类型等,返回后我们按照和后台约定的格式,根据后台返回的信息,直接进行反射和调用即可。

假设和后台约定格式如下:

@{
     /类名
     @"className" : @"UserListViewController", 
     /数据参数
     @"propertys" : @{ @"name": @"liuxiaozhuang", 
                       @"age": @3 },
     /调用方法名
     @"method" : @"refreshUserInformation"
 };

定义一个UserListViewController类,这个类用于测试,在实际使用中可能会有多个这样的控制器类。

#import <UIKit>
/由于使用的KVC赋值,如果不想把这两个属性暴露出来,把这两个属性写在.m文件也可以
@interface UserListViewController : UIViewController
@property (nonatomic,strong) NSString *name;/*!< 用户名 */
@property (nonatomic,strong) NSNumber *age;/*!< 用户年龄 */
/** 使用反射机制反射为SEL后,调用的方法 */
- (void)refreshUserInformation;
@end

下面通过反射机制简单实现了控制器跳转的方法,在实际使用中再根据业务需求进行修改即可。因为这篇文章主要是讲反射机制,所以没有使用runtime代码。

简单封装的页面跳转方法,只是做演示,代码都是没问题的,使用时可以根据业务需求进行修改。

- (void)remoteNotificationDictionary:(NSDictionary *)dict {
    /根据字典字段反射出我们想要的类,并初始化控制器
    Class class = NSClassFromString(dict[@"className"]);
    UIViewController *vc = [[class alloc] init];
    /获取参数列表,使用枚举的方式,对控制器属性进行KVC赋值
    NSDictionary *parameter = dict[@"propertys"];
    [parameter enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        /在属性赋值时,做容错处理,防止因为后台数据导致的异常
        if ([vc respondsToSelector:NSSelectorFromString(key)]) {
            [vc setValue:obj forKey:key];
        }
    }];
    [self.navigationController pushViewController:vc animated:YES];
    /从字典中获取方法名,并调用对应的方法
    SEL selector = NSSelectorFromString(dict[@"method"]);
    [vc performSelector:selector];
}

更多:iOS面试题大全(附答案)

收藏
0
sina weixin mail 回到顶部
浪到家!打花的球差点输了 勇士咋还不长心 北京市网信办副主任陈华涉嫌严重违纪违法被查 西甲官方公布新赛季赛程:10月28日踢国家德比 《巴伦周刊》:通用电气前景黯淡 今日华南大雨东北降雪 这些地区气温猛跌要注意 阿尔及利亚一架军机坠毁:死亡人数升至257人 22日13时视频直播国象联赛第5轮:雷挺婕VS朱锦尔 多省市试水“公务员聘任制” 如何杜绝萝卜招聘? 代表委员热议国务院机构改革:更好服务人民 申花战恒大海报:为胜利一同战斗 三连胜PK四连胜 董事长纪委书记被查后 安徽一国企又有干部落马 原油飙升带来全球通胀 美联储加息步伐恐加快
大豆种植有了“双保险” 白银底部信号出现 玉米谨防高位风险 假挂单真做市?揭秘山寨币\"代投私募\"的地下利益链条 王健委员:建议设立国家级“雷锋奖章” 天舟一号总设计师揭秘:人类定居火星还要多久? 经济强劲的体现?美债收益率18年来首超其他发达国家 老詹膨胀了,这么吹自己的真是前所未有! 美商务部终裁中越工具箱产品存在倾销行为 势赢交易5月18日操作建议:黑色分化 苹果多头不改 苏炳添退役到底咋回事? 已是苏教授不再属广东队 中国代表队将出战2018ISF世界小球场足球联盟世界杯 曝国青小将800万转会华夏 母队:不会设太多阻碍
王宝山:无谓失误毁掉好局 创造很多机会但功亏一篑 山东威海政府原党组成员徐连新被双开 涉职务犯罪 英媒:济州岛难民风波后 韩国或将收紧难民政策 新京报:法国限制外资买农地 不妨多些开放心态 男子1600万奖票被扔状告官方 律师:或不了了之 沈琼:北京外援并不可怕 赛制漫长才刚开始 伊以“叙利亚战争\"骤然升级 德黑兰:袭击毫无根据 三六零定增百亿方案出炉 大安全战略正式启动 英零售商乐购9月或将推出连锁折扣店 我出钱谁愿意为我卖命 养100只肉狗投资多钱 怎么在家里挣钱 现在什么行业挣钱快 AG亚游集团