NSClassFromString那点事

本文探讨了在iOS开发中,如何利用反射机制,特别是NSClassFromString方法在Objective-C和Swift中的应用差异。通过示例代码,阐述了在不同语言环境下,如何动态获取并使用类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       相信码农们都听说过反射这个词,今天要说的iOS下的反射使用方法。虽然在Object-C和Swift中都使用NSClassFromString这个方法,但是在使用过程中还是有细微的差别。具体看下面的代码注释吧

  • Object-C中使用
Class urlClass = NSClassFromString(controllerValue);  //controllerValue为待反射的类名
id toController = [[urlClass alloc] initWithNibName:controllerValue bundle:nil];
if ([toController isKindOfClass:[BaseViewController class]]) {
    UIViewController *currentController = [self getCurrentViewController];
    ((BaseViewController *)toController).pushNotification = self.pushNotice;
    [currentController.navigationController pushViewController:toController animated:YES];
}
           Object-C中NSClassFromString调用时传入的参数就是直接的类名,相信在Object-C中使用过该方法的人,都会用,非常简单
 
  • Swift中使用
if  let appName: String = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName") as? String {
    let classStringName: String = String(format: "%@.%@", appName, controllerName) //此处多加了一个app的名字
    if let toClass: UIViewController.Type = NSClassFromString(classStringName) as? UIViewController.Type {
       	let toController: UIViewController = toClass.init(nibName: controllerName, bundle: nil)
    	self.navigationController?.pushViewController(toController, animated: true)
    }
}
            Swift中NSClassFromString调用时,在类名前增加了App的名字,有点像Java中反射调用时的包路径吧(我猜其实就是)
  • 未搞明白的问题
            Swift中直接在AppDelegate这个类中调用NSClassFromString就不需要加App名,个人猜测难道是在根路径下不用加?如有搞明白的请告知,谢谢!附上代码为证
let toClass: UIViewController.Type? = NSClassFromString(controllerValue!) as? UIViewController.Type
if toClass != nil {
    let currentController: UIViewController = self.getCurrentViewController()
    let toController: UIViewController = toClass!.init(nibName: controllerValue!, bundle: nil)
    currentController.navigationController?.pushViewController(toController, animated: true)
}



补充一下,最近在拿这个反射功能时,发现在iOS版本低于9时,如果使用xib布局,加载时,会出现异想不到的问题,必须使用明确的写法,如:
      var toController: UIViewController?
                switch self.toControllerName! {
                case "MessageListViewController":
                    toController = MessageListViewController(nibName: "MessageListViewController", bundle: nil)
                    break
                case "ServiceCardViewController":
                    toController = ServiceCardViewController(nibName: "ServiceCardViewController", bundle: nil)
                    break
                default:
                    break
                }

所以让我更加确信,iOS9在工程文件管理这块有类Java中的包概念,而9以下版本没有此概念,因此上面这样的写法在iOS9中可以使用,而iOS9以下不适用。需要进一步找到方法,待找到更合适的方法,我会持续更新此文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值