阅读源码之: ReactiveObjC第一篇开章

2021-02-23  本文已影响0人  LV大树

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)

上一篇下一篇

猜你喜欢

热点阅读