ReactiveCocoa 学习笔记八(RACBlockTrampoline)

RACBlockTrampoline

RACBlockTrampoline 类是 ReactiveCocoa 框架中内部使用的类,用于调用动态的回调代码块。

+ (id)invokeBlock:(id)block withArguments:(RACTuple *)arguments {
	NSCParameterAssert(block != NULL);

	RACBlockTrampoline *trampoline = [[self alloc] initWithBlock:block];
	return [trampoline invokeWithArguments:arguments];
}

要正常使用该方法,block 不能为空,并且其所包含的参数必须和 arguments 的分量个数保持一致,且参数是必须的,当然最多支持 15 个参数。

- (id)invokeWithArguments:(RACTuple *)arguments {
	SEL selector = [self selectorForArgumentCount:arguments.count];
	NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
	invocation.selector = selector;
	invocation.target = self;

	for (NSUInteger i = 0; i < arguments.count; i++) {
		id arg = arguments[i];
		NSInteger argIndex = (NSInteger)(i + 2);
		[invocation setArgument:&arg atIndex:argIndex];
	}

	[invocation invoke];
	
	__unsafe_unretained id returnVal;
	[invocation getReturnValue:&returnVal];
	return returnVal;
}

这个方法很简单,首先调用下面的方法,根据 arguments 所包含的分量个数确定 block 中的参数个数,从而确定后面需要调用的方法。

- (SEL)selectorForArgumentCount:(NSUInteger)count {
	NSCParameterAssert(count > 0);

	switch (count) {
		case 0: return NULL;
		case 1: return @selector(performWith:);
		case 2: return @selector(performWith::);
		···	 //省略
		case 15: return @selector(performWith:::::::::::::::);
	}
	NSCAssert(NO, @"The argument count is too damn high! Only blocks of up to 15 arguments are currently supported.");
	return NULL		
}

根据返回的 SEL 变量创建一个 NSInvocation 实例,而后绑定参数,最后调用 invoke 方法。


如果要在框架外使用该类,需要导入 RACBlockTrampoline.h 头文件。

#import "RACBlockTrampoline.h"

- (void)test {
    id (^block)(id obj) = ^ id (id obj) {
        NSLog(@"block is executed : %@ .",obj);
        return obj;
    };
    
    id obj = [RACBlockTrampoline invokeBlock:block withArguments:RACTuplePack(@100)];
}

你可能感兴趣的:(ReactiveCocoa,ReactiveCocoa)