0%

ios-class-from-string

OC的NSClassFromString跟Java的Class.forName非常类似。快速了解一下。

相关知识

通过名字获取类

NSClassFromString - Obtains a class by name.

备注:对应于Java的Class.forName()

OC代码如下:

1
NSObject *target = [[NSClassFromString(className) alloc] init];

对应的Java代码如下:

1
2
3
4
5
6
// 简单起见这里忽略异常处理
Class<?> clazz = Class.forName(className);
Object target = clazz.newInstance();

// Java 9
// Object target = clazz.getDeclaredConstructor().newInstance()

通过名字获取方法

NSSelectorFromString - Returns the selector with a given name.

OC代码如下:

1
SEL action = NSSelectorFromString(methodName);

对应的Java代码如下:

1
Method catMethod = SomeClass.class.getDeclaredMethod(methodName);

上面代码中需要说明一下的是SEL。它的定义是:

1
typedef struct objc_selector *SEL;

它的作用是 Defines an opaque type that represents a method selector.

另一个要注意的OC中通过可以直接通过名字获取到对应的selector,并不需要借助Object或Class;而Java中不能直接通过名字获取到对应的Method,而需要借助Class。

判断方法是否能调用

[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
2
3
if (![target respondsToSelector:action]){
// ...
};

Java中没有对应的用法

动态调用方法

[NSInvocation invoke] - Sends the receiver’s message (with arguments) to its target and sets the return value.

OC代码如下:

1
2
3
NSMethodSignature* methodSig = [target methodSignatureForSelector:action];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation invoke];

对应的Java代码如下:

1
2
Method action = ...
action.invoke(target);

实例

问题现象:

  • 反序列化时不成功
  • 提交加载相关类后,反序列化成功

代码:

原因: