NSClassFromString 用法简介
简单了解如何使用 NSClassFromString()
函数动态加载类。
NSClassFromString 及相关函数
OC | Java | 备注 | |
---|---|---|---|
通过名字获取类 | NSClassFromString() | Class.forName() | |
通过名字获取方法 | NSSelectorFromString() | Class.getDeclaredMethod() | |
判断方法能否调用 | [NSObject respondsToSelector] | ||
动态调用方法 | [NSInvocation invoke] | Method.invoke() |
NSClassFromString 介绍
NSClassFromString()
函数的作用是通过名字来获取类 (原文:Obtains a class by name.)。
这个函数接受类的名字(一个字符串)作为参数,返回值是对应的类对象(如果这个名字对应的类未加载,则返回 nil
)。如果参数为 nil
,则直接返回 nil
。
OC 的 NSClassFromString()
跟 Java 的 Class.forName()
类似。
OC 代码如下:
1 | NSObject *target = [[NSClassFromString(className) alloc] init]; |
对应的 Java 代码如下:
1 | // 简单起见这里忽略异常处理 |
NSSelectorFromString 介绍
NSSelectorFromString()
函数的作用是通过名字来获取 selector (原文:Returns the selector with a given name)。
这个函数接受 selector 的名字(一个字符串)作为参数,返回值是对应的 selector。如果参数为 nil
或者无法转换成 UTF-8 字符串,则直接返回 (SEL)0
。
OC 的 NSSelectorFromString()
跟 Java 的 Class.getDeclaredMethod()
方法类似。
OC 代码如下:
1 | SEL action = NSSelectorFromString(methodName); |
对应的 Java 代码如下:
1 | Method catMethod = SomeClass.class.getDeclaredMethod(methodName); |
注意:
SEL
的定义是 typedef struct objc_selector *SEL;
。它的用于定义代表 method selector 的类型 (原文:Defines an opaque type that represents a method selector)。
判断方法是否能调用
[NSObject] - (BOOL)respondsToSelector:(SEL)aSelector;
- Returns a Boolean value that indicates whether the receiver implements or inherits a method that can respond to a specified message.
1 | if (![target respondsToSelector:action]){ |
Java中没有对应的用法。
动态调用方法
[NSInvocation invoke]
- Sends the receiver’s message (with arguments) to its target and sets the return value.
OC代码如下:
1 | NSMethodSignature* methodSig = [target methodSignatureForSelector:action]; |
对应的Java代码如下:
1 | Method action = ... |
NSStringClass 使用案例
可以使用 NSStringClass()
动态加载类。如果返回 nil
,表示不能加载此类。
如下面代码所示,有不同的方式创建对象:
1 | // 方式一 |
通常来说这两种方式没有太多区别。但是,如果并不存在 MyClass
这个类,那么方式二编译报错。所以如果不确定是否存在 MyClass
这个类的情况下,应当使用方式一来创建对象。
方式一有这样两个好处:
- “弱”链接
- 不需要使用
import
。即使没有头文件,只要类存在,就可以创建其对象
再来看一个实例。某项目需要兼容 v4.3 和 v6.0 版本的百度地图SDK(有点怪,是吧)
- 百度地图SDK v4.3 - 没有
BMKCustomMapStyleOption
,不支持自定义地图功能 - 百度地图SDK v6.0 - 有
BMKCustomMapStyleOption
,支持自定义地图功能
原先的代码是这样写的:
1 | BMKCustomMapStyleOption *options = [[BMKCustomMapStyleOption alloc] init]; |
当使用百度地图SDK v6.0时,这行代码工作正常;当使用百度地图SDK v4.3时,这行代码无法编译,提示 BMKCustomMapStyleOption
引起 “Undefined symbols”。
我们可以使用 NSClassFromString
避免这里的编译错误:
1 | id options = [[NSClassFromString(@"BMKCustomMapStyleOption") alloc] init]; |
完整代码如下:
1 | // MyBMapSettingsAdapter.m |