RACTypeParsing
在 ReactiveCocoa 框架中,为 NSInvocation 类扩展了一个 RACTypeParsing 分类。该分类提供了快速设置、获取方法参数的方法,并且提供了一个类型为 RACTuple 的属性。
- 设置参数
- (void)rac_setArgument:(id)object atIndex:(NSUInteger)index;
该方法会设置指定索引的参数,其主要是先从方法签名中获取参数的类型,而后根据其类型的不同定义不同的变量,最后将变量的地址传递给参数索引。主要是使用 PULL_AND_SET
宏,定义如下:
#define PULL_AND_SET(type, selector) \
do { \
type val = [object selector]; \
[self setArgument:&val atIndex:(NSInteger)index]; \
} while (0)
- 获取参数
- (id)rac_argumentAtIndex:(NSUInteger)index;
该方法可以获取指定索引处的参数,并且最终返回的是 Objective C 对象。在确定指定参数的类型后,使用宏 WRAP_AND_RETURN
进行包装。
#define WRAP_AND_RETURN(type) \
do { \
type val = 0; \
[self getArgument:&val atIndex:(NSInteger)index]; \
return @(val); \
} while (0)
- 获取返回值
- (id)rac_returnValue;
获取的返回值也是经过 WRAP_AND_RETURN
宏处理的,最后返回的也是一个 OC 对象。
#define WRAP_AND_RETURN(type) \
do { \
type val = 0; \
[self getReturnValue:&val]; \
return @(val); \
} while (0)
- 参数集合
@property (nonatomic, copy) RACTuple *rac_argumentsTuple;
通过获取或设置该属性,来读取参数或设置参数。
- (RACTuple *)rac_argumentsTuple {
NSUInteger numberOfArguments = self.methodSignature.numberOfArguments;
NSMutableArray *argumentsArray = [NSMutableArray arrayWithCapacity:numberOfArguments - 2];
for (NSUInteger index = 2; index < numberOfArguments; index++) {
[argumentsArray addObject:[self rac_argumentAtIndex:index] ?: RACTupleNil.tupleNil];
}
return [RACTuple tupleWithObjectsFromArray:argumentsArray];
}
读取方法中的所有参数,然后将所有参数封装到一个 RACTuple 实例变量中。若参数为 nil ,则使用 RACTupleNil 表示。
- (void)setRac_argumentsTuple:(RACTuple *)arguments {
NSCAssert(arguments.count == self.methodSignature.numberOfArguments - 2, @"Number of supplied arguments (%lu), does not match the number expected by the signature (%lu)", (unsigned long)arguments.count, (unsigned long)self.methodSignature.numberOfArguments - 2);
NSUInteger index = 2;
for (id arg in arguments) {
[self rac_setArgument:(arg == RACTupleNil.tupleNil ? nil : arg) atIndex:index];
index++;
}
}
将 RACTuple 中的变量赋值给方法中的参数,对于 RACTupleNil 则赋值 nil 。