NSClassFromString的用法

本文详细介绍了Objective-C中的反射机制,包括NSClassFromString与NSStringFromClass的使用方法,以及它们在动态创建类对象和进行类型检查方面的应用。同时,还探讨了NSStringFromSelector与NSSelectorFromString的功能,并解释了如何通过这些函数实现更灵活的编程。

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

NSClassFromString与NSStringFromClass

1>NSClassFromString()用于利用一个字符串来创建一个类或对象,例如:

     NSString *myClassStr = @"myClass";   
     Class myClazz = NSClassFromString(myClassStr);  
     if (myClazz) {  
         id myClassInit = [[myClazz alloc] init];  
     }  

NSClassFromString 将NSString转换成一个Class,如果不存在,返回一个nil

正常来说,
 id myObj = [[NSClassFromString(@"MySpecialClass") alloc] init];
 id myObj = [[MySpecialClass alloc] init];
两者是一样的。但是,如果你的程序中并不存在MySpecialClass这个类,下面的写法会出错,而上面的写法只是返回一个空对象而已。
因此,在某些情况下,可以使用NSClassFromString来进行你不确定的类的初始化。
例如: 在一个tableView示例方法中用到的NSClassFromString

//创建控制器数组(将类名存储在数组中)

- (NSArray *)viewControllers{
    if (!_viewControllers) {
        _viewControllers = [@[@"XWMagicMoveController", @"XWPresentOneController", @"XWPageCoverController", @"XWCircleSpreadController"] copy];
    }
    return _viewControllers;
}

//不确定到底取到数组中哪一个控制器(通过runTime中的NSClassFromString方法,创建控制器对象)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [self.navigationController pushViewController:[[NSClassFromString(self.viewControllers[indexPath.row]) alloc] init] animated:YES];
}

NSClassFromString的好处是
    1. 弱化连接,因此并不会把没有的Framework也link到程序中。

    2 .不需要使用import,因为类是动态加载的,只要存在就可以加载。因此如果你的toolchain中没有某个类的头文件定义,而你确信这个类是可以用的,那么也可以用这种方法。

2>NSStringFromClass()是获取与类型名称同名字的字符串,例如:

MyModel *model=[MyModel  alloc] init];
   NSString *responseClass =NSStringFromClass([model class]);

这里一定要注意NSStringFromClass()中要传的参数为Class类型,不要直接把model传进去。

3>总结:这两个函数一般用在什么地方呢?

  1.用下一些用到反射设计模式的框架上,动态创建类的对象
  2.用于一些逻辑的判断。
对于第一种应用,熟悉框架的开发者应该都用过,简单说下第二种
比如我判断返回的model类型是不是NSDictionary类型
    Bool bb=[[model class] isKindOfClass:[NSDictionary class]] ;  
    或者  
    Bool cc=([model class]==[NSDictionary class]]);  
    或者  
    Bool dd=NSStringFromClass([[model class]isEqualToString:@“ NSDictionary”]  

NSStringFromSelector与NSSelectorFromString

1>NSStringFromSelector   将SEL对象转换为NSString对象 

 SEL sel=@selector(compare:); 

 NSString * functionName= NSStringFromSelector(sel);

2>NSSelectorFromString  将一个字符串方法转换成为SEL对象  

 NSString * functionName= NSStringFromSelector(sel);

 SEL anotherSel=NSSelectorFromString(方法名字的字符串);

3>总结:

在编译时设置变量为SEL变量最有效的方法就是@selector()指令。然而,在某些情况下,你可能需要在运行时转换一个字符串为一个selector。
我们得到 SEL变量之后,可以通过下面的调用来给一个对象发送消息:

[对象 performSelector:SEL变量 withObject:参数1 withObject:参数2]; 

这样的机制增加了程序的灵活性,可以通过给一个方法传递sel参数,让这个方法动态的执行某一个方法,我们也可以通过配置文件制定需要执行的方法,程序读取配置文件之后把方法的字符串翻译成sel变量然后给相应的对象发送这个消息

从效率的角度上来说,执行的时候不是通过方法名字而是通过方法的ID来查找方法,由于整数的查找比匹配字符串快得多,所以这样可以在某种程序上提高执行的效率


结构体转字符串相互转换方法

结构体转字符串
NSString *  NSStringFromCGPoint(CGPoint point);
NSString *  NSStringFromCGVector(CGVector vector);
NSString *  NSStringFromCGSize(CGSize size);
NSString *  NSStringFromCGRect(CGRect rect);
NSString *  NSStringFromCGAffineTransform(CGAffineTransform transform);
NSString *  NSStringFromUIEdgeInsets(UIEdgeInsets insets);
NSString *  NSStringFromUIOffset(UIOffset offset);

字符串转结构体
CGPoint    CGPointFromString(NSString *string);
CGVector  CGVectorFromString(NSString *string);
CGSize     CGSizeFromString(NSString *string);
CGRect     CGRectFromString(NSString *string);   //我们在监听高度变化时需要用这个 ,获取键盘的frame 值,就是从一个 string类型中取出 CGRect!
CGAffineTransform CGAffineTransformFromString(NSString *string);
UIEdgeInsets  UIEdgeInsetsFromString(NSString *string);//距离边界的距离,上左下右的顺序!
UIOffset    UIOffsetFromString(NSString *string); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值