阅读源码之: ReactiveObjC第一篇开章
RAC 是一个基于响应式的框架,类似于RacSwift ,各大语言都有类似的实现。
本文只是简单的归类下RAC for OC
拓展部分:
1.基于视图类的:
MK + AnnotaionView
UI + ActionSheet, AlertView, BarButton, Button, Collection, Control,DatePicker, ImagePickerController, RefreshControl, SegmentedControl,Slider, Stepper, Switch , TableView , TableViewCell, TableViewHeaderFooterView , TextField, TextView
基于数据的
NS + Array, Data, Dictionary, Enumerator, FileHandle, IndexSet, OrderedSet, Set, String,
基于模型的
NS + Object,
基于通讯的
NS + NotificationCenter, URLConnection,
基于操作的
NS + Invocation
UI + GestureRecognizer
基于储存的
NS + UserDefaults,
RAC 主要类的解读:
RACBlockTrampoline
//一个标准的NSInvocation的写法
- (id)invokeWithArguments:(RACTuple *)arguments {
SEL selector = [self selectorForArgumentCount:arguments.count];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];//先确定是否有该方法SEL
invocation.selector = selector;//设置SEL
invocation.target = self; //设置target
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;
}
- (SEL)selectorForArgumentCount:(NSUInteger)count {
NSCParameterAssert(count > 0);
switch (count) {//这里说明了,参数最多为15个,如果过多的参数,可能会引起栈容量不足?
case 0: return NULL;
case 1: return @selector(performWith:);
case 2: return @selector(performWith::);
case 3: return @selector(performWith:::);
case 4: return @selector(performWith::::);
case 5: return @selector(performWith:::::);
case 6: return @selector(performWith::::::);
case 7: return @selector(performWith:::::::);
case 8: return @selector(performWith::::::::);
case 9: return @selector(performWith:::::::::);
case 10: return @selector(performWith::::::::::);
case 11: return @selector(performWith:::::::::::);
case 12: return @selector(performWith::::::::::::);
case 13: return @selector(performWith:::::::::::::);
case 14: 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;
}
- (id)performWith:(id)obj1 {
id (^block)(id) = self.block;
return block(obj1);
}
- (id)performWith:(id)obj1 :(id)obj2 {
id (^block)(id, id) = self.block;
return block(obj1, obj2);
}
- (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 {
id (^block)(id, id, id) = self.block;
return block(obj1, obj2, obj3);
}
...下同,不断增加obj的个数,直到枚举的15个参数
遍历可变参数,示例:
+ (instancetype)tupleWithObjects:(id)object, ... {
va_list args;//声明list args
va_start(args, object);//获取list args
NSUInteger count = 0;
for (id currentObject = object; currentObject != nil; currentObject = va_arg(args, id)) {
//va_arg(args,id) 获取下一个obj
++count;
}
va_end(args);
if (count == 0) {
return [[self alloc] init];
}
NSMutableArray *objects = [[NSMutableArray alloc] initWithCapacity:count];
va_start(args, object);
for (id currentObject = object; currentObject != nil; currentObject = va_arg(args, id)) {
[objects addObject:currentObject];
}
va_end(args);
return [[self alloc] initWithBackingArray:objects];
}
发现一个有意思的东西: NSFastEnumeration
遵守该协议后,就可以实现下标访问和快速枚举forin.
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id __unsafe_unretained [])buffer count:(NSUInteger)len {
return [self.backingArray countByEnumeratingWithState:state objects:buffer count:len];
}
NSValueTransformer 值转换,与其说是一个抽象类,不如说是一个协议,毕竟转换都得手写实现。
管理值变换的名字和值变换对象的mapping方法。
+valueTransformerNames 返回所有注册的子类转换器
+setValueTransformer:forName: 并不是注册子类,而是注册NSValueTransformer子类的实例。这样,提供常用功能的值变换,可以用不同的名称不同的参数多次注册。
+valueTransformerForName: 子类转换器实例的取得(Singleton)