美文网首页
阅读源码之: ReactiveObjC第一篇开章

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

作者: LV大树 | 来源:发表于2021-02-23 10:49 被阅读0次

    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)

    相关文章

      网友评论

          本文标题:阅读源码之: ReactiveObjC第一篇开章

          本文链接:https://www.haomeiwen.com/subject/bgekfltx.html