NSClassFromString通过classString构造class然后实例化一个对象

时间:2022-10-20 09:21:30

起因是看蓝牙demo的时候看到这个关键字的 就搜索了一下。。

+ (BOOL)isBluetoothSupported{

 // Only for iOS 6.0

 if(NSClassFromString(@"CBPeripheralManager")==nil){

   return NO;

  }


NSClassFromString是一个很有用的东西,尤其在进行iPhone toolchain的开发上。

正常来说,

id myObj = [[NSClassFromString(@"MySpecialClass") alloc] init];

id myObj = [[MySpecialClass alloc] init];

是一样的。但是,如果你的程序中并不存在MySpecialClass这个类,下面的写法会出错,而上面的写法只是返回一个空对象而已。

因此,在某些情况下,可以使用NSClassFromString来进行你不确定的类的初始化。

比如在iPhone中,NSTask可能就会出现这种情况,所以在你需要使用NSTask时,最好使用:

[[NSClassFromString(@"NSTask") .....]]

而不要直接使用[NSTask ...]这种写法。

NSClassFromString的好处是:

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

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


///////////////////////////////////////////////////////////

只是搜索到了 不知道是否有用


通过classString构造class然后实例化一个对象的过程很简单。如下 

C代码  NSClassFromString通过classString构造class然后实例化一个对象
  1. NSString *myClassStr @"myClass" 
  2. Class myClazz NSClassFromString(myClassStr);  
  3. if (myClazz)  
  4.     id myClassInit [[myClazz alloc] init];  
  5.  



前不久遇到一个问题,"主工程(MainProject)"调"静态库工程(LibProject)"的方法实例化对象,目标类存在于LibProject中,构造方法如下 

C代码  NSClassFromString通过classString构造class然后实例化一个对象
  1. +(id)getObjectWithClassName:(NSString *)aClassName  
  2.     id rtnObject nil;  
  3.     Class myClazz NSClassFromString(aClassName);  
  4.     if (myClazz)  
  5.          rtnObject [[myClazz alloc] init];  
  6.      
  7.     return rtnObject;  
  8.  



每次都返回nil,同时很确定的一点是这个类肯定存在,于是在主工程直接反射创建对象,同样是nil。 
进一步做了一个实验 
1. 在主工程的MainViewController中 #import"MyClassForTest.h" 
2. -(void)test { 
   NSLog(@"wzf===>%@",[MyClassForTestclass]); 
    ClassmyClazz =NSClassFromString(@"MyClassForTest"); 
   NSLog(@"wzf===>%@",[myClazz class]); 

这样就能够得到, = =! 

搜索了一个google,在*中有人提出了同样的问题(http://*.com/questions/2227085/nsclassfromstring-returns-nil) 
有人提到了文档中的解释 “Return Value :The class object named by aClassName, ornil if no class by that name is currently loaded. If aClassName isnil, returns nil.”依照其解释,如果返回的是nil的话,要吗不存在这个“aClassName”,要吗是"没有loaded"。排除前一项,只能存在于后一项,那就是“此时未加载”。 
因此联想到了,Other Lind Flag中的“-all_load”设置,这个就是解决问题的关键。 
"-all_load"设置方式,选择MainProject.xcodeproject的MainProject(target)在Build Setting中找到Other Link ...添加上就可以了 


///////////////////////////////////////////////////////////

类似的函数如下:
NSClassFromString
NSGetSizeAndAlignment
NSLog
NSLogv
NSSelectorFromString
NSStringFromClass
NSStringFromSelector


NSStringFromSelector


SEL sel=@selector(compare:);

NSString *functionName= NSStringFromSelector(sel);

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

在编译时设置变量为SEL变量最有效的方法就是@selector()指令。然而,在某些情况下,你可能需要在运行时转换一个字符串为一个selector。

第一行是直接在程序里面写上方法的名字,第2行是通过sel变量获取方法的名字。第三行是写上方法名字的字符串.

我们得到 SEL变量之后,可以通过下面的调用来给一个对象发送消息:

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

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

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